Fix charts

Signed-off-by: András Schmelczer <andras@schmelczer.dev>
This commit is contained in:
Andras Schmelczer 2022-04-10 22:25:47 +02:00
parent 4b92a75841
commit 5b92d22f75
5 changed files with 51 additions and 26 deletions

View file

@ -1,9 +1,11 @@
from pathlib import Path
from typing import Any, Dict, List
from fastapi import FastAPI, status
from fastapi.middleware.wsgi import WSGIMiddleware
from fastapi.openapi.docs import get_swagger_ui_html
from fastapi.responses import RedirectResponse
from fastapi.staticfiles import StaticFiles
from starlette.responses import HTMLResponse
from ..context import get_context
@ -11,6 +13,8 @@ from ..helper import snake_case_to_text
from ..metrics import create_dash_app
from ..views import HealthCheckResponse, Query
PATH = Path(__file__).parent.resolve()
def create_fastapi_app(
function_name: str, disable_docs: bool, disable_metrics: bool
@ -40,6 +44,10 @@ def create_fastapi_app(
def redirect_to_entrypoint() -> RedirectResponse:
return RedirectResponse("/metrics")
app.mount(
"/assets", StaticFiles(directory=PATH / "../metrics/assets"), name="static"
)
@app.post("/query", status_code=status.HTTP_200_OK)
def query_metrics(query: Query) -> List[Dict[str, Any]]:
return get_context().persistence.query(

View file

@ -2,6 +2,7 @@ from typing import Any, Callable
import uvicorn
from fastapi import FastAPI, status
from uvicorn.config import LOGGING_CONFIG
from ..tracing import TracingContext
from ..views import Trace
@ -32,8 +33,7 @@ def serve(
host="0.0.0.0",
port=5050,
log_config={
"version": 1,
"disable_existing_loggers": False,
**LOGGING_CONFIG,
"formatters": {
"default": {
"()": "good_ai.logger.CustomFormatter",
@ -44,26 +44,5 @@ def serve(
"fmt": "%(asctime)s | %(levelname)8s | %(message)s", # noqa: E501
},
},
"handlers": {
"default": {
"formatter": "default",
"class": "logging.StreamHandler",
"stream": "ext://sys.stderr",
},
"access": {
"formatter": "access",
"class": "logging.StreamHandler",
"stream": "ext://sys.stdout",
},
},
"loggers": {
"uvicorn": {"handlers": ["default"], "level": "INFO"},
"uvicorn.error": {"level": "INFO"},
"uvicorn.access": {
"handlers": ["access"],
"level": "INFO",
"propagate": False,
},
},
},
)

View file

@ -0,0 +1,3 @@
body {
background-color: hotpink;
}

View file

@ -7,6 +7,8 @@ from dash import Dash, dash_table, dcc, html
from dash.dependencies import Input, Output
from flask import Flask
from good_ai.utilities.unique import unique
from ..context import get_context
from ..helper import snake_case_to_text
from ..views import SortBy
@ -15,10 +17,16 @@ from .get_filter_from_datatable import get_filter_from_datatable
def create_dash_app(function_name: str) -> Flask:
flask_app = Flask(__name__)
app = Dash(
function_name,
requests_pathname_prefix=get_context().metrics_path + "/",
server=flask_app,
title=snake_case_to_text(function_name),
update_title=None,
external_stylesheets=[
"/assets/index.css",
],
)
documents = get_context().persistence.get_documents()
@ -117,8 +125,34 @@ def create_dash_app(function_name: str) -> Flask:
)
df = pd.DataFrame(rows)
return px.parallel_coordinates(
df, labels={c: snake_case_to_text(c) for c in df.columns}
return go.Figure(
go.Parcoords(
dimensions=[
get_dimension_descriptor(df, c)
for c in df.columns
if not c.startswith("arg:") and c not in {"id", "created"}
]
)
)
return app.server
return flask_app
def get_dimension_descriptor(df: pd.DataFrame, column: str) -> Dict[str, Any]:
dimension: Dict[str, Any] = {
"label": snake_case_to_text(column),
}
values = df[column]
try:
dimension["values"] = [float(v) for v in values]
except (TypeError, ValueError):
unique_values = unique(values)
value_mapping = {str(v): i for i, v in enumerate(unique_values)}
dimension["values"] = [value_mapping[str(v)] for v in values]
dimension["tickvals"] = list(value_mapping.values())
dimension["ticktext"] = list(value_mapping.keys())
return dimension

View file

@ -1,4 +1,5 @@
from typing import Literal
from typing_extensions import TypedDict