Metrics
Application Kit provides request counting and metrics collection through decorators and dependencies.
Overview
The metrics system tracks request counts per endpoint and queues them to Redis for processing. This enables:
- Usage tracking per project
- Billing and quota management
Not for analytics
This metrics system is designed for billing and quota enforcement, not user behavior analytics. It counts API calls per project to track usage against subscription limits.
Usage
Use the AddJobToMetrics dependency:
"""FastAPI metrics example."""
from functools import partial
from fastapi import APIRouter, Depends
from application_kit.fastapi.fastapi import get_fastapi_app
from application_kit.fastapi.metrics import AddJobToMetrics
app = get_fastapi_app("api")
router = APIRouter()
app.include_router(router)
# Create a partial for your service
add_stores_metric = partial(AddJobToMetrics, "STORES")
@router.get(
"/search",
dependencies=[Depends(add_stores_metric("search"))],
)
async def search() -> dict[str, list[str]]:
return {"results": []}
Note
The AddJobToMetrics dependency uses FastAPI's BackgroundTasks to send the job to Redis after the response is sent.
Use the @count_request decorator:
"""Django metrics example."""
from django.http import HttpRequest, JsonResponse
from application_kit.django.decorators import authenticate_key, count_request
@authenticate_key()
@count_request("search", "STORES")
def search_view(request: HttpRequest) -> JsonResponse:
return JsonResponse({"results": []})
@authenticate_key()
@count_request("search", "STORES")
async def async_search_view(request: HttpRequest) -> JsonResponse:
return JsonResponse({"results": []})
Use the Django @count_request decorator with @chain():
"""Django Ninja metrics example."""
from django.http import HttpRequest
from application_kit.django.decorators import authenticate_key, count_request
from application_kit.shinobi.api import WoosmapApi
from application_kit.shinobi.authentication import PublicKeyAuth
from application_kit.shinobi.decorators import chain, terminate
api = WoosmapApi(description="My API")
@api.get("/search", auth=[PublicKeyAuth()])
@chain(authenticate_key(), count_request("search", "STORES"))
@terminate()
def search(request: HttpRequest) -> dict[str, list[str]]:
return {"results": []}
Parameters
| Parameter | Type | Description |
|---|---|---|
product |
str |
Product category (first argument to partial) |
endpoint_name |
str |
Identifier for the endpoint |
| Parameter | Type | Description |
|---|---|---|
endpoint_name |
str |
Identifier for the endpoint (e.g., "search") |
product |
str |
Product category (e.g., "STORES", "MAPS") |
Configuration
Add the metrics_queue Redis dependency to your application.json:
{
"dependencies": {
"databases": [
{
"name": "metrics_queue",
"type": "redis",
"extras": {"queue_prefix": "counter"}
}
]
}
}
The queue_prefix determines the Redis key prefix for the metrics queue.
How It Works
-
When a request is processed, the decorator/dependency creates a job with:
- Organization and project IDs
- Endpoint name
- Product category
- Timestamp
-
The job is pushed to a Redis queue (using the
queue_prefix) -
A background worker processes the queue and aggregates metrics
API Reference
application_kit.fastapi.metrics
AddJobToMetrics
AddJobToMetrics(product, kind)
AddJobToMetrics dependency
Source code in application_kit/fastapi/metrics.py
13 14 15 | |
application_kit.django.decorators
count_request
count_request(request_name, product, name_lambda=None)
Counts the request, must be placed after authenticate_key or authenticate_user decorator.
Source code in application_kit/django/decorators.py
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | |