qfa.api.routes_usage#

API route handlers for the usage-tracking endpoints.

Owns its own APIRouter; mounted by create_app alongside the main router. Carved out of routes.py so the analyze/summarize/coding flow isn’t interleaved with usage-stat marshalling.

Functions

usage(tenant, usage_repo, from_, to)

Usage statistics for the authenticated tenant within an optional window.

usage_all_by_operation(_tenant, usage_repo, ...)

Per-operation and grand-total usage statistics.

usage_all_by_tenant(_tenant, usage_repo, ...)

Per-tenant and grand-total usage statistics.

async qfa.api.routes_usage.usage(tenant: TenantApiKey = Depends(dependency=<function authenticate_request>, use_cache=True, scope=None), usage_repo: UsageRepositoryPort = Depends(dependency=<function get_usage_repo>, use_cache=True, scope=None), from_: datetime | None = Query(None), to: datetime | None = Query(None)) UsageStatsResponse[source]#

Usage statistics for the authenticated tenant within an optional window.

The response carries two views of the same data:

  • Per-invocation (inherited top-level fields): each distinct call_id counts as one. Multi-LLM-call operations (e.g. /v1/assign_codes) collapse to a single entry. call_duration sums the LLM-call durations within one invocation — equal to wall-clock latency for sequential invocations, overestimating wall-clock when the orchestrator fans out LLM calls in parallel via asyncio.gather.

  • Per-LLM-call (llm_call_stats): each LLM call attempt counts as one. Identical semantics to the pre-#91 behaviour. Use this when you want today’s “every row counts as one call” view.

operations carries a per-operation breakdown of the same data. Each entry has the same shape (per-invocation top-level + llm_call_stats). The list is sorted by total_cost_usd descending with ties broken by operation ascending; operations with zero calls in the window are omitted.

`failed_calls` semantics (per-invocation top-level): an invocation counts as failed only when every LLM call within its call_id has status='error'. Mixed-status invocations do NOT count. Failed-only invocations are excluded from the per-invocation distributions (so failures cannot skew latency/token quantiles) but their cost is still summed into total_cost_usd — the grand total reflects what was actually spent, including invocations the provider billed before erroring. Every individual error row is still counted in llm_call_stats.failed_calls.

Backwards-compatible numerics: total_cost_usd, input_tokens.total, and output_tokens.total are unchanged vs. the pre-#91 implementation. Numerics that have changed semantics for multi-LLM-call operations: total_calls, failed_calls, and every avg/min/max/p5/p95 field. Clients needing the previous semantics should read llm_call_stats.

Parameters:
  • tenant (TenantApiKey) – The authenticated tenant.

  • usage_repo (UsageRepositoryPort) – The usage repository.

  • from (datetime | None) – Inclusive lower bound (UTC tz-aware), or None.

  • to (datetime | None) – Exclusive upper bound (UTC tz-aware), or None.

Returns:

Aggregated usage statistics for the tenant in the time window.

Return type:

UsageStatsResponse

async qfa.api.routes_usage.usage_all_by_tenant(_tenant: TenantApiKey = Depends(dependency=<function require_superuser>, use_cache=True, scope=None), usage_repo: UsageRepositoryPort = Depends(dependency=<function get_usage_repo>, use_cache=True, scope=None), from_: datetime | None = Query(None), to: datetime | None = Query(None)) AllUsageStatsResponse[source]#

Per-tenant and grand-total usage statistics. Requires superuser access.

Response shape: tenants is a list of per-tenant TenantUsageStats (sorted alphabetically by tenant_id); total is the cross-tenant grand total (tenant_id is null). Every entry — per-tenant and grand-total — carries the same dual-view shape as GET /v1/usage: per-invocation top-level fields, an llm_call_stats block with the per-LLM-call view, and an operations tuple sorted by cost desc (ties: operation asc, empties omitted).

Tenants with zero calls in the window are filtered from tenants. The total entry is always present (zero-filled when the window is empty).

See GET /v1/usage for the full per-field semantic contract, including the per-invocation failed_calls rule and the backwards-compatibility note on which numerics changed. For the inverse hierarchy (operations top-level, tenants nested), see GET /v1/usage/all/by-operation.

Parameters:
  • _tenant (TenantApiKey) – The authenticated superuser tenant.

  • usage_repo (UsageRepositoryPort) – The usage repository.

  • from (datetime | None) – Inclusive lower bound (UTC tz-aware), or None.

  • to (datetime | None) – Exclusive upper bound (UTC tz-aware), or None.

Returns:

Per-tenant and grand total usage statistics within the window.

Return type:

AllUsageStatsResponse

async qfa.api.routes_usage.usage_all_by_operation(_tenant: TenantApiKey = Depends(dependency=<function require_superuser>, use_cache=True, scope=None), usage_repo: UsageRepositoryPort = Depends(dependency=<function get_usage_repo>, use_cache=True, scope=None), from_: datetime | None = Query(None), to: datetime | None = Query(None)) AllUsageByOperationResponse[source]#

Per-operation and grand-total usage statistics. Requires superuser access.

Inverse hierarchy of GET /v1/usage/all/by-tenant: top-level aggregation is by orchestrator operation, with a nested tenants breakdown under each operation. Useful for answering “where is the spend going, regardless of tenant” and “which tenants drive each operation”.

Response shape: operations is a list of per-operation OperationUsageStats (sorted by total_cost_usd desc, ties broken by operation asc); total is the cross-operation grand total (operation is null). Every entry — per-operation and grand-total — carries per-invocation top-level fields, an llm_call_stats block with the per-LLM-call view, and a tenants tuple sorted by cost desc (ties: tenant_id asc, empties omitted).

Operations with zero calls in the window are filtered from operations. The total entry is always present (zero-filled when the window is empty).

See GET /v1/usage for the full per-field semantic contract, including the per-invocation failed_calls rule and the backwards-compatibility note on which numerics changed.

Parameters:
  • _tenant (TenantApiKey) – The authenticated superuser tenant.

  • usage_repo (UsageRepositoryPort) – The usage repository.

  • from (datetime | None) – Inclusive lower bound (UTC tz-aware), or None.

  • to (datetime | None) – Exclusive upper bound (UTC tz-aware), or None.

Returns:

Per-operation and grand total usage statistics within the window.

Return type:

AllUsageByOperationResponse