first
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
"""Google Analytics 4 - Data API (reporting).
|
||||
|
||||
Thin passthrough: request bodies are the GA4 Data API request objects and
|
||||
responses are returned as-is. See
|
||||
https://developers.google.com/analytics/devguides/reporting/data/v1/rest
|
||||
|
||||
Credentials: X-GA-Access-Token (preferred) or X-GA-Credentials. See
|
||||
``app.credentials.get_ga_credentials``.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from fastapi import APIRouter, Body, Depends, Path
|
||||
|
||||
from ..clients.ga_client import GoogleAnalyticsClient
|
||||
from ..credentials import GaCredentials, get_ga_credentials
|
||||
|
||||
router = APIRouter(prefix="/ga/data", tags=["google-analytics: data"])
|
||||
|
||||
# Reused OpenAPI example for report request bodies.
|
||||
_RUN_REPORT_EXAMPLE = {
|
||||
"dateRanges": [{"startDate": "7daysAgo", "endDate": "today"}],
|
||||
"dimensions": [{"name": "country"}],
|
||||
"metrics": [{"name": "activeUsers"}],
|
||||
}
|
||||
|
||||
|
||||
def _property(property_id: str) -> str:
|
||||
# Accept both "123456789" and "properties/123456789".
|
||||
pid = property_id.strip()
|
||||
return pid if pid.startswith("properties/") else f"properties/{pid}"
|
||||
|
||||
|
||||
@router.post(
|
||||
"/properties/{property_id}/runReport",
|
||||
summary="Run a GA4 report",
|
||||
)
|
||||
async def run_report(
|
||||
property_id: str = Path(..., description="GA4 property id, e.g. 123456789"),
|
||||
body: dict[str, Any] = Body(..., examples=[_RUN_REPORT_EXAMPLE]),
|
||||
creds: GaCredentials = Depends(get_ga_credentials),
|
||||
) -> Any:
|
||||
client = GoogleAnalyticsClient(creds)
|
||||
return await client.data_post(f"/{_property(property_id)}:runReport", body)
|
||||
|
||||
|
||||
@router.post(
|
||||
"/properties/{property_id}/runPivotReport",
|
||||
summary="Run a GA4 pivot report",
|
||||
)
|
||||
async def run_pivot_report(
|
||||
property_id: str = Path(..., description="GA4 property id"),
|
||||
body: dict[str, Any] = Body(...),
|
||||
creds: GaCredentials = Depends(get_ga_credentials),
|
||||
) -> Any:
|
||||
client = GoogleAnalyticsClient(creds)
|
||||
return await client.data_post(
|
||||
f"/{_property(property_id)}:runPivotReport", body
|
||||
)
|
||||
|
||||
|
||||
@router.post(
|
||||
"/properties/{property_id}/batchRunReports",
|
||||
summary="Run up to 5 GA4 reports in one call",
|
||||
)
|
||||
async def batch_run_reports(
|
||||
property_id: str = Path(..., description="GA4 property id"),
|
||||
body: dict[str, Any] = Body(...),
|
||||
creds: GaCredentials = Depends(get_ga_credentials),
|
||||
) -> Any:
|
||||
client = GoogleAnalyticsClient(creds)
|
||||
return await client.data_post(
|
||||
f"/{_property(property_id)}:batchRunReports", body
|
||||
)
|
||||
|
||||
|
||||
@router.post(
|
||||
"/properties/{property_id}/batchRunPivotReports",
|
||||
summary="Run up to 5 GA4 pivot reports in one call",
|
||||
)
|
||||
async def batch_run_pivot_reports(
|
||||
property_id: str = Path(..., description="GA4 property id"),
|
||||
body: dict[str, Any] = Body(...),
|
||||
creds: GaCredentials = Depends(get_ga_credentials),
|
||||
) -> Any:
|
||||
client = GoogleAnalyticsClient(creds)
|
||||
return await client.data_post(
|
||||
f"/{_property(property_id)}:batchRunPivotReports", body
|
||||
)
|
||||
|
||||
|
||||
@router.post(
|
||||
"/properties/{property_id}/runRealtimeReport",
|
||||
summary="Run a GA4 realtime report",
|
||||
)
|
||||
async def run_realtime_report(
|
||||
property_id: str = Path(..., description="GA4 property id"),
|
||||
body: dict[str, Any] = Body(...),
|
||||
creds: GaCredentials = Depends(get_ga_credentials),
|
||||
) -> Any:
|
||||
client = GoogleAnalyticsClient(creds)
|
||||
return await client.data_post(
|
||||
f"/{_property(property_id)}:runRealtimeReport", body
|
||||
)
|
||||
|
||||
|
||||
@router.post(
|
||||
"/properties/{property_id}/checkCompatibility",
|
||||
summary="Check dimension/metric compatibility for a GA4 report",
|
||||
)
|
||||
async def check_compatibility(
|
||||
property_id: str = Path(..., description="GA4 property id"),
|
||||
body: dict[str, Any] = Body(...),
|
||||
creds: GaCredentials = Depends(get_ga_credentials),
|
||||
) -> Any:
|
||||
client = GoogleAnalyticsClient(creds)
|
||||
return await client.data_post(
|
||||
f"/{_property(property_id)}:checkCompatibility", body
|
||||
)
|
||||
|
||||
|
||||
@router.get(
|
||||
"/properties/{property_id}/metadata",
|
||||
summary="List available GA4 dimensions and metrics for a property",
|
||||
)
|
||||
async def get_metadata(
|
||||
property_id: str = Path(..., description="GA4 property id"),
|
||||
creds: GaCredentials = Depends(get_ga_credentials),
|
||||
) -> Any:
|
||||
client = GoogleAnalyticsClient(creds)
|
||||
return await client.data_get(f"/{_property(property_id)}/metadata")
|
||||
Reference in New Issue
Block a user