REST API¶
FastAPI application serving attribution data.
Application Factory¶
app
¶
FastAPI application factory for the Music Attribution API.
Provides the create_app factory function and the lifespan async
context manager that boots the async database engine on startup and
disposes it on shutdown. All route modules (attribution, permissions,
health, metrics, CopilotKit) are registered here.
The application follows the attribution-by-design philosophy described in the companion paper (Teikari 2026, Section 4) — provenance metadata is embedded at creation time rather than retrofitted post-hoc.
Notes
CORS origins are read from Settings.cors_origins (comma-separated).
The database engine is stored on app.state so that route-level
dependencies can access it without global singletons.
lifespan
async
¶
Manage the async database engine lifecycle.
Creates the SQLAlchemy async engine and session factory on startup,
attaches them to app.state, and disposes the engine on shutdown.
| PARAMETER | DESCRIPTION |
|---|---|
app
|
The FastAPI application instance whose
TYPE:
|
| YIELDS | DESCRIPTION |
|---|---|
None
|
Control is yielded to the application between startup and shutdown. |
Source code in src/music_attribution/api/app.py
create_app
¶
Create and configure the FastAPI application.
Instantiates the FastAPI app with metadata, CORS middleware, and all
route modules. The lifespan context manager handles database
engine startup and shutdown.
| RETURNS | DESCRIPTION |
|---|---|
FastAPI
|
Fully configured FastAPI application ready to serve. |
Notes
Route prefixes:
/health— health check (no prefix)/metrics— Prometheus metrics (no prefix)/api/v1/attributions/— attribution CRUD/api/v1/permissions/— permission checks/api/v1/copilotkit— AG-UI / CopilotKit SSE endpoint
Examples:
>>> from music_attribution.api.app import create_app
>>> app = create_app()
>>> app.title
'Music Attribution API'
Source code in src/music_attribution/api/app.py
Dependencies¶
dependencies
¶
Shared database session helper for route modules.
Provides get_session which extracts the async_sessionmaker from
request.app.state and returns a new AsyncSession. This module
is the single source of truth for obtaining a database session in
API route handlers — no route module should define its own session helper.
The session factory is created in the lifespan context manager
(see music_attribution.api.app) and stored on app.state.
get_session
¶
Get an async session from the application's session factory.
| PARAMETER | DESCRIPTION |
|---|---|
request
|
FastAPI request object with access to
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
AsyncSession
|
A new async database session. Caller must use it as a context
manager ( |
Source code in src/music_attribution/api/dependencies.py
Attribution Routes¶
attribution
¶
Attribution query endpoints backed by async PostgreSQL repository.
Provides CRUD-style read endpoints for attribution records:
GET /api/v1/attributions/work/{work_id}— single attribution by work IDGET /api/v1/attributions/— paginated list with optional filtersGET /api/v1/attributions/{attribution_id}/provenance— provenance chainGET /api/v1/attributions/search— hybrid search via RRF fusion
All endpoints return JSON representations of AttributionRecord
domain objects. The provenance endpoint exposes the full evidence chain
with uncertainty metadata, enabling Perplexity-style inline source
references (see companion paper, Section 5.2).
Notes
Sessions are obtained from app.state.async_session_factory via the
shared get_session helper in dependencies.
get_attribution_by_work_id
async
¶
Get a single attribution record by work entity ID.
GET /api/v1/attributions/work/{work_id}
Looks up the attribution record associated with a specific musical work entity. Returns 404 if no attribution exists for the given ID.
| PARAMETER | DESCRIPTION |
|---|---|
request
|
FastAPI request with access to
TYPE:
|
work_id
|
UUID of the work entity to look up.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
dict
|
JSON-serializable attribution record. |
| RAISES | DESCRIPTION |
|---|---|
HTTPException
|
404 if no attribution is found for the given |
Source code in src/music_attribution/api/routes/attribution.py
list_attributions
async
¶
list_attributions(
request: Request,
limit: int = Query(default=50, ge=1, le=100),
offset: int = Query(default=0, ge=0),
needs_review: bool | None = Query(default=None),
assurance_level: str | None = Query(default=None),
) -> list[dict]
List attribution records with pagination, filtering, and sorting.
GET /api/v1/attributions/
Returns attribution records ordered by confidence score (descending).
Supports pagination via limit/offset and optional filtering
by needs_review flag or assurance_level tier (A0-A3).
| PARAMETER | DESCRIPTION |
|---|---|
request
|
FastAPI request with access to
TYPE:
|
limit
|
Maximum number of records to return (1-100), by default 50.
TYPE:
|
offset
|
Number of records to skip for pagination, by default 0.
TYPE:
|
needs_review
|
If
TYPE:
|
assurance_level
|
Filter by assurance level value (e.g.,
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[dict]
|
JSON-serializable list of attribution records sorted by confidence score descending. |
Source code in src/music_attribution/api/routes/attribution.py
get_provenance
async
¶
Get the full provenance chain with uncertainty metadata.
GET /api/v1/attributions/{attribution_id}/provenance
Returns the ordered provenance chain (evidence trail) and the uncertainty summary for a specific attribution record. This data enables Perplexity-style inline source references in the frontend, where each claim can be traced back to its originating data source.
The uncertainty summary includes conformal prediction intervals and source agreement metrics (see companion paper, Section 5.2).
| PARAMETER | DESCRIPTION |
|---|---|
request
|
FastAPI request with access to
TYPE:
|
attribution_id
|
UUID of the attribution record whose provenance is requested.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
dict
|
Dictionary with keys:
|
| RAISES | DESCRIPTION |
|---|---|
HTTPException
|
404 if no attribution record exists for the given ID. |
Source code in src/music_attribution/api/routes/attribution.py
search_attributions
async
¶
search_attributions(
request: Request,
q: str = Query(
default="",
max_length=500,
description="Search query",
),
limit: int = Query(default=20, ge=1, le=100),
) -> list[dict]
Hybrid search across attribution records using RRF fusion.
GET /api/v1/attributions/search
Combines three retrieval signals via Reciprocal Rank Fusion (RRF):
- Full-text search (PostgreSQL
tsvector) - Vector similarity (pgvector cosine distance)
- Graph context (entity relationship traversal)
This multi-signal approach reduces the risk of any single retrieval method dominating results.
| PARAMETER | DESCRIPTION |
|---|---|
request
|
FastAPI request with access to
TYPE:
|
q
|
Search query string, by default
TYPE:
|
limit
|
Maximum number of results to return (1-100), by default 20.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[dict]
|
List of dictionaries, each containing:
|
Source code in src/music_attribution/api/routes/attribution.py
Permission Routes¶
permissions
¶
Permission check endpoints backed by async PostgreSQL repository.
Provides MCP-compatible permission query endpoints:
POST /api/v1/permissions/check— check a single permissionGET /api/v1/permissions/{entity_id}— list all permission bundles
These endpoints implement machine-readable permission queries for AI training rights, following the MCP as consent infrastructure model described in the companion paper (Section 6). Each permission check is audit-logged for transparency and compliance.
Notes
Permission bundles use the PermissionTypeEnum to represent
training, derivative-work, commercial-use, and other permission types.
The audit trail records who asked, when, and with what context.
PermissionCheckRequest
¶
Bases: BaseModel
Request body for a permission check query.
| ATTRIBUTE | DESCRIPTION |
|---|---|
entity_id |
UUID of the entity whose permissions are being queried (e.g., a recording or work entity).
TYPE:
|
permission_type |
Permission type string matching a
TYPE:
|
scope_entity_id |
Optional UUID to scope the permission check to a specific context (e.g., a particular AI model or service).
TYPE:
|
requester_id |
Identifier for the requesting party, by default
TYPE:
|
PermissionCheckResponse
¶
Bases: BaseModel
Response body for a permission check query.
| ATTRIBUTE | DESCRIPTION |
|---|---|
entity_id |
UUID of the entity whose permission was checked.
TYPE:
|
permission_type |
The permission type that was queried.
TYPE:
|
result |
Permission result value (e.g.,
TYPE:
|
check_permission
async
¶
check_permission(
request: Request, body: PermissionCheckRequest
) -> PermissionCheckResponse
Check a specific permission for an entity.
POST /api/v1/permissions/check
Queries the permission repository for the given entity and permission type, then records an audit log entry. This implements the machine-readable consent query pattern described in the companion paper (Section 6).
| PARAMETER | DESCRIPTION |
|---|---|
request
|
FastAPI request with access to
TYPE:
|
body
|
JSON request body containing the entity ID, permission type, optional scope entity, and requester identifier.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
PermissionCheckResponse
|
The permission check result with entity ID, type, and outcome. |
Source code in src/music_attribution/api/routes/permissions.py
list_permissions
async
¶
List all permission bundles for an entity.
GET /api/v1/permissions/{entity_id}
Returns every permission bundle associated with the given entity UUID. Each bundle contains the full set of permissions (training, derivative work, commercial use, etc.) and their current status.
| PARAMETER | DESCRIPTION |
|---|---|
request
|
FastAPI request with access to
TYPE:
|
entity_id
|
UUID of the entity whose permission bundles are requested.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[dict]
|
JSON-serializable list of permission bundle dictionaries. |
| RAISES | DESCRIPTION |
|---|---|
HTTPException
|
404 if no permission bundles exist for the given entity. |
Source code in src/music_attribution/api/routes/permissions.py
Health Routes¶
health
¶
Health check endpoint for the Music Attribution API.
Provides a minimal GET /health endpoint used by container
orchestrators (Docker health checks, Kubernetes liveness probes) and
uptime monitors to verify the service is running.
The endpoint does not check database connectivity — it only confirms
that the FastAPI process is alive and able to serve HTTP responses.
For deeper health checks, see the /metrics endpoint.
health_check
async
¶
Return a simple health status for the service.
GET /health
Returns a static JSON object confirming the service is alive. This endpoint is intentionally cheap — no database queries, no external calls.
| RETURNS | DESCRIPTION |
|---|---|
dict[str, str]
|
Dictionary with |
Examples:
>>> import httpx
>>> resp = httpx.get("http://localhost:8000/health")
>>> resp.json()
{'status': 'healthy', 'service': 'music-attribution-api'}
Source code in src/music_attribution/api/routes/health.py
Metrics Routes¶
metrics
¶
Prometheus metrics endpoint for the Music Attribution API.
Exposes GET /metrics in Prometheus exposition format for scraping
by Prometheus, Grafana Agent, or any OpenMetrics-compatible collector.
The endpoint is excluded from the OpenAPI schema
(include_in_schema=False) so it does not appear in the Swagger UI
or auto-generated client stubs.
Notes
Metrics are collected via the prometheus_client default registry
(REGISTRY). Custom counters and histograms for attribution
pipeline stages can be registered elsewhere and will automatically
appear here.
metrics
async
¶
Serve Prometheus metrics in exposition format.
GET /metrics
Serialises all registered Prometheus collectors into the plain-text
exposition format (version 0.0.4). The response content type is
set to text/plain; version=0.0.4; charset=utf-8 as required by
the Prometheus scraping protocol.
| RETURNS | DESCRIPTION |
|---|---|
Response
|
FastAPI |
Notes
This endpoint is hidden from the OpenAPI schema to avoid cluttering the public API documentation.