Quaudio landing
# quaudio
API routes
Registered endpoints and supported methods.
| Path | Methods | Name |
|---|---|---|
| /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 externalfoundry-agentsviaFOUNDRY_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
python -m venv .venv && source .venv/bin/activatepip install --upgrade pip buildbash ./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 commentsissues: write- Interacts with PR (PRs are issues in GitHub API)checks: write- Creates status checks that block mergingcontents: 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
developmentbranch 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
mainbranch 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:
- Add unit tests for new code
- Ensure edge cases are covered
- Run locally:
pytest --cov=quaudio --cov-report=html - 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-> externalfoundry-agentsviaFOUNDRY_ENDPOINT. - Deployment smoke tests now validate
quantum_functiononly.
/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
200with fields includingquantum_coherence,classification, andrecommendations. - Returns
400whenaudio_metricsis 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
200withstatus,filename, optionalmodel, andanalysispayload. - Returns
422when required fields are missing (filename,file_b64). - Returns
400whenfile_b64is 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.cosmosdoes not exportCosmosClient/PartitionKeyat 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 outputtest_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 responsetest_upload_skips_non_mp3: Uploads a non-MP3 file and checks it is skippedtest_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