Quaudio
Quaudio · FastAPI service

Quaudio landing

# quaudio

API routes

Registered endpoints and supported methods.

PathMethodsName
/openapi.json GET HEAD openapi
/auth/login GET login_form
/auth/login POST login_submit
/auth/token POST get_token
/auth/token/refresh POST refresh_token
/auth/logout POST logout
/auth/logout GET logout_page
/ GET landing_page
/docs GET swagger_ui
/upload GET upload_page
/routes GET list_routes
/upload POST upload
/agent/analyze POST agent_analyze
/agent/analyze/foundry POST agent_analyze_foundry
/agent/function_ping GET agent_function_ping
/debug GET debug_dashboard
/debug/data GET debug_data
/debug/logfile GET debug_logfile
/debug/env GET debug_env

Project README

Live content from the repository README.md. Open README

quaudio

Lightweight FastAPI microservice for processing MP3 uploads, extracting ID3 metadata, and delegating quantum/ML analysis to an Azure-hosted Foundry Agent. The repo includes local stubs and production-ready wiring (Managed Identity, Cosmos DB, Key Vault, and CI/CD templates).

Quick overview

  • quaudio/ — main FastAPI service that accepts MP3 uploads at POST /upload.
  • quaudio/tags.py — mp3 tag extraction (mutagen).
  • quaudio/services/foundry_analyzer.py — client that calls the external Foundry service for audio analysis.
  • quaudio/contracts/ — API contracts for service-to-service communication.
  • foundry_function (legacy adapter) has been removed; use external foundry-agents via FOUNDRY_ENDPOINT.
  • infra/main.bicep — basic Bicep template to provision Storage, Functions, Cosmos DB, Key Vault and outputs.
  • tests/ — unit tests and small integration-style checks.

Build a wheel for foundry-agents

  1. python -m venv .venv && source .venv/bin/activate
  2. pip install --upgrade pip build
  3. bash ./scripts/build_quaudio_wheel.sh

This creates dist/quaudio-<version>-py3-none-any.whl and copies it into ../foundry-agents/packages/ when that repo sits alongside this one. Point foundry-agents function app requirements.txt files at that wheel (e.g., --find-links ../../packages with quaudio==0.2.0) to consume the artifact instead of installing the source tree.

Configuration: Using the Config Class

All configuration in quaudio is managed via the Config class, which supports environment variables, dictionaries, and custom getters. This enables dependency injection and test isolation for all components.

Basic usage:

from quaudio.config import Config
config = Config()
value = config.get('MY_SETTING')
flag = config.get_bool('USE_FEATURE', False)

Injecting config for tests:

test_config = Config({'USE_COSMOS_DB': 'true', 'COSMOS_ENDPOINT': 'https://example.com'})
container = get_cosmos_container(config=test_config)

Migration notes:

  • All direct environment variable access has been replaced by Config.
  • All tests now inject config instead of monkeypatching environment variables.
  • For boolean flags, use string values ('true', 'false').

Requirements

  • Python 3.12
  • Local tooling (optional): Azure CLI, Bicep CLI

All dependencies have been consolidated into a single requirements.txt file for simplified installation and CI/CD.

Install project dependencies:

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

This single command installs all dependencies including:

  • FastAPI and web framework components
  • Azure SDK packages (Cosmos DB, Key Vault, Identity)
  • Testing tools (pytest, pytest-cov, pytest-asyncio)
  • Audio processing (mutagen)
  • Documentation tools (Sphinx, myst-parser)

See docs/REQUIREMENTS_CONSOLIDATION.md for details.

For complete environment variable standardization and examples across quaudio and foundry-agents, see ../ENVIRONMENT.md.

Dependency compatibility (FastAPI/Starlette/httpx)

This service uses FastAPI 0.101.1 and Starlette 0.27.0. Starlette's TestClient relies on httpx internals that changed in newer versions, so we intentionally pin:

  • Starlette: 0.27.0
  • httpx: 0.24.1

If you upgrade any of these packages, please validate in a clean virtual environment first:

python -m venv .venv-tmp
./.venv-tmp/bin/python -m pip install --upgrade pip
./.venv-tmp/bin/python -m pip install -r requirements.txt
./.venv-tmp/bin/python -m pytest -q
rm -rf .venv-tmp

CI/CD Pipeline Architecture

Quaudio uses a two-tier CI/CD approach for separation of concerns:

1. GitHub Actions - Unit Testing (.github/workflows/ci.yml)

Purpose: Fast feedback on code quality through unit tests only.

Triggers: Every push and pull request to development or main branches.

What it does:

  • ✅ Runs all unit tests with pytest
  • ✅ Generates coverage report (HTML + XML)
  • Enforces 70% minimum coverage threshold
  • ✅ Fails the build (blocks PR merging) if coverage < 70%
  • ✅ Posts coverage status as PR comment
  • ✅ Uploads coverage artifacts for review

Required Permissions:

The workflow includes explicit GitHub Actions permissions for PR interactions:

  • pull-requests: write - Posts coverage reports as PR comments
  • issues: write - Interacts with PR (PRs are issues in GitHub API)
  • checks: write - Creates status checks that block merging
  • contents: read - Reads repository code

Note: If you fork this repo, these permissions are already configured in .github/workflows/ci.yml. Without them, you'll see: HttpError: Resource not accessible by integration

Why GitHub Actions?

  • Fast execution (~2-3 minutes)
  • No Azure resource dependencies
  • Immediate feedback for developers
  • Prevents low-quality code from entering codebase

2. Azure Pipelines - Integration & Deployment (azure-pipelines.yml)

Purpose: Integration testing with real Azure resources and automated deployment.

Triggers: Push to development or main branches, and pull requests.

Pipeline stages:

Stage 1: Integration Tests

  • Runs integration tests that interact with real Azure services
  • Uses Azure service principal for authentication
  • Tests Cosmos DB, Key Vault, and other Azure integrations

Stage 2: Deploy to Development

  • Condition: Only on development branch after integration tests pass
  • Deploys infrastructure using Bicep templates
  • Creates/updates development environment
  • Configures managed identities and RBAC roles

Stage 3: Deploy to Production

  • Condition: Only on main branch after dev deployment succeeds
  • Deploys to production environment
  • Full infrastructure provisioning with production settings
  • Requires manual approval via Azure DevOps environments

Why Azure Pipelines?

  • Deep integration with Azure resources
  • Managed identities for secure authentication
  • Environment-based approvals for production
  • Infrastructure as Code deployment
  • Service connection management

Coverage Requirements

Minimum threshold: 70%
Current coverage: 97%

If your PR causes coverage to drop below 70%, the GitHub Actions workflow will fail, preventing the PR from being merged. To fix:

  1. Add unit tests for new code
  2. Ensure edge cases are covered
  3. Run locally: pytest --cov=quaudio --cov-report=html
  4. View coverage report: open htmlcov/index.html

Workflow Summary

Developer Push/PR
    ↓
GitHub Actions (Unit Tests)
    ├─ ✅ Pass (>70% coverage) → Allow merge
    └─ ❌ Fail (<70% coverage) → Block merge

Merge to development
    ↓
Azure Pipelines
    ├─ Integration Tests
    ├─ Deploy to Dev Environment
    └─ (Manual approval)

Merge to main
    ↓
Azure Pipelines
    ├─ Integration Tests
    ├─ Deploy to Dev Environment
    ├─ Deploy to Production
    └─ (Manual approval required)

For complete setup instructions, see docs/CI_CD_SETUP.md.

API Endpoints

Legacy Function Removal

The legacy azure_functions/foundry_function adapter has been removed.

  • Current production path: quaudio -> external foundry-agents via FOUNDRY_ENDPOINT.
  • Deployment smoke tests now validate quantum_function only.

/upload (POST)

Upload one or more MP3 files for metadata extraction and analysis.

/routes (GET)

Returns a list of all registered API routes and their methods.

  • Accept: application/json — Returns JSON with all routes
  • Accept: text/html — Returns a formatted HTML page with a JSON viewer
  • Uses a Jinja2 template for the HTML view (quaudio/templates/routes.html)

Example JSON response:

{
  "routes": [
    {"path": "/upload", "methods": ["POST"], "name": "upload_mp3"},
    {"path": "/routes", "methods": ["GET"], "name": "list_routes"},
    ...
  ]
}

Example HTML view:

  • Syntax-highlighted JSON
  • "Copy JSON" button
  • Responsive, dark-themed layout

/agent/analyze (POST)

Analyzes lightweight audio metrics using the integrated quantum analyzer.

Request body:

{
  "audio_metrics": {
    "bpm": 128,
    "energy": 0.8,
    "danceability": 0.75
  }
}

Behavior:

  • Returns 200 with fields including quantum_coherence, classification, and recommendations.
  • Returns 400 when audio_metrics is missing or invalid.

/agent/analyze/foundry (POST)

Analyzes base64 audio content by forwarding the request to the external Foundry service.

Request body:

{
  "filename": "song.mp3",
  "file_b64": "UklGRiQAAABXQVZF...",
  "tags": {
    "title": "Example Song",
    "artist": "Example Artist",
    "genre": "Rock"
  },
  "model": "discogs-maest-30s-pw-129e"
}

Behavior:

  • Returns 200 with status, filename, optional model, and analysis payload.
  • Returns 422 when required fields are missing (filename, file_b64).
  • Returns 400 when file_b64 is not valid base64.

OpenAPI schemas:

  • Request model: FoundryAgentAnalyzeRequest
  • Response model: FoundryAgentAnalyzeResponse

Cosmos SDK compatibility

This project now handles Azure Cosmos SDK import-path differences more defensively in repository/provider layers and tests.

  • Supports environments where azure.cosmos does not export CosmosClient/PartitionKey at the top level.
  • Maintains testability by allowing monkeypatching across SDK variants.
  • Prevents import-time failures from masking unrelated functionality.

Template Usage

The HTML view for /routes is rendered using Jinja2:

  • Template file: quaudio/templates/routes.html
  • Context variables: title, heading, subtitle, data (routes JSON)
  • Easily customizable for other API views

Testing

Unit tests for /routes endpoint are in tests/test_routes_endpoint.py:

  • test_routes_json: Verifies JSON output
  • test_routes_html: Verifies HTML output and page content

Run all tests:

pytest

Run focused endpoint tests:

pytest tests/test_agents_endpoint.py -q

/upload endpoint tests

Unit tests for the upload endpoint are in tests/test_upload_api.py:

  • test_upload_happy_path: Uploads a valid MP3 and checks response
  • test_upload_skips_non_mp3: Uploads a non-MP3 file and checks it is skipped
  • test_upload_no_files: Checks error response when no files are uploaded

Legacy stub-based tests are in tests/test_upload_endpoint.py (for reference only).

Run all tests:

pytest