diff --git a/chart/main.py b/chart/main.py index e873f58..ad8d21d 100644 --- a/chart/main.py +++ b/chart/main.py @@ -3,13 +3,13 @@ import psycopg2 import uvicorn import yaml import matplotlib.pyplot as plt -import locale import datetime import dateutil.relativedelta from fastapi import FastAPI, Response, status from psycopg2.extras import DictCursor from starlette.staticfiles import StaticFiles +from middleware.plausible_analytics import PlausibleAnalytics app = FastAPI() @@ -30,6 +30,7 @@ if not os.path.exists('../charts'): app.mount('/static/charts', StaticFiles(directory='../charts/')) +app.middleware('http')(PlausibleAnalytics()) @app.get("/api/getChart/") async def get_chart(response: Response, diff --git a/chart/middleware/plausible_analytics.py b/chart/middleware/plausible_analytics.py new file mode 100644 index 0000000..5e0cca5 --- /dev/null +++ b/chart/middleware/plausible_analytics.py @@ -0,0 +1,42 @@ +import httpx +import yaml + +from user_agents import parse as ua_parse + +config = yaml.safe_load(open('../config.yaml')) + +class PlausibleAnalytics: + async def __call__(self, request, call_next): + response = await call_next(request) + + user_agent = request.headers.get('user-agent', 'unknown') + user_agent_parsed = ua_parse(user_agent) + + event = { + "domain": config['analytics']['plausible_domain'], + "name": request.url.path or '404 - Not Found', + "url": str(request.url), + "props": { + "method": request.method, + "statusCode": response.status_code, + "browser": f"{user_agent_parsed.browser.family} {user_agent_parsed.browser.version_string}", + "os": f"{user_agent_parsed.os.family} {user_agent_parsed.os.version_string}", + "source": request.headers.get('referer', 'direct'), + }, + } + + async with httpx.AsyncClient() as client: + try: + await client.post( + config['analytics']['plausible_api'], + json=event, + headers={ + "Authorization": f"Bearer {config['analytics']['plausible_token']}", + "Content-Type": "application/json", + "User-Agent": request.headers.get('user-agent', 'unknown'), + }, + ) + except Exception as e: + print(f"Error sending event to Plausible: {e}") + + return response