mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-02-06 04:45:10 -05:00
We'll soon be needing a more feature-complete external API. To make way for this, I'm moving some files around so: - We can more easily create new versions of our external API - The file structure of our internal API is more homogeneous These changes are quite opinionated, but IMO in any case they're better than the chaotic structure we have now. ### Changes 🏗️ - Move `backend/server` -> `backend/api` - Move `backend/server/routers` + `backend/server/v2` -> `backend/api/features` - Change absolute sibling imports to relative imports - Move `backend/server/v2/AutoMod` -> `backend/executor/automod` - Combine `backend/server/routers/analytics_*test.py` -> `backend/api/features/analytics_test.py` - Sort OpenAPI spec file ### Checklist 📋 #### For code changes: - [x] I have clearly listed my changes in the PR description - [x] I have made a test plan - [x] I have tested my changes according to the test plan: - CI tests - [x] Clicking around in the app -> no obvious breakage
77 lines
2.3 KiB
Python
77 lines
2.3 KiB
Python
"""Analytics API"""
|
|
|
|
import logging
|
|
from typing import Annotated
|
|
|
|
import fastapi
|
|
import pydantic
|
|
from autogpt_libs.auth import get_user_id
|
|
from autogpt_libs.auth.dependencies import requires_user
|
|
|
|
import backend.data.analytics
|
|
|
|
router = fastapi.APIRouter(dependencies=[fastapi.Security(requires_user)])
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class LogRawMetricRequest(pydantic.BaseModel):
|
|
metric_name: str = pydantic.Field(..., min_length=1)
|
|
metric_value: float = pydantic.Field(..., allow_inf_nan=False)
|
|
data_string: str = pydantic.Field(..., min_length=1)
|
|
|
|
|
|
@router.post(path="/log_raw_metric")
|
|
async def log_raw_metric(
|
|
user_id: Annotated[str, fastapi.Security(get_user_id)],
|
|
request: LogRawMetricRequest,
|
|
):
|
|
try:
|
|
result = await backend.data.analytics.log_raw_metric(
|
|
user_id=user_id,
|
|
metric_name=request.metric_name,
|
|
metric_value=request.metric_value,
|
|
data_string=request.data_string,
|
|
)
|
|
return result.id
|
|
except Exception as e:
|
|
logger.exception(
|
|
"Failed to log metric %s for user %s: %s", request.metric_name, user_id, e
|
|
)
|
|
raise fastapi.HTTPException(
|
|
status_code=500,
|
|
detail={
|
|
"message": str(e),
|
|
"hint": "Check analytics service connection and retry.",
|
|
},
|
|
)
|
|
|
|
|
|
@router.post("/log_raw_analytics")
|
|
async def log_raw_analytics(
|
|
user_id: Annotated[str, fastapi.Security(get_user_id)],
|
|
type: Annotated[str, fastapi.Body(..., embed=True)],
|
|
data: Annotated[
|
|
dict,
|
|
fastapi.Body(..., embed=True, description="The data to log"),
|
|
],
|
|
data_index: Annotated[
|
|
str,
|
|
fastapi.Body(
|
|
...,
|
|
embed=True,
|
|
description="Indexable field for any count based analytical measures like page order clicking, tutorial step completion, etc.",
|
|
),
|
|
],
|
|
):
|
|
try:
|
|
result = await backend.data.analytics.log_raw_analytics(
|
|
user_id, type, data, data_index
|
|
)
|
|
return result.id
|
|
except Exception as e:
|
|
logger.exception("Failed to log analytics for user %s: %s", user_id, e)
|
|
raise fastapi.HTTPException(
|
|
status_code=500,
|
|
detail={"message": str(e), "hint": "Ensure analytics DB is reachable."},
|
|
)
|