Skip to content

AudioLab Registry API Documentation

Complete API documentation for querying the AudioLab module registry.

Overview

The AudioLab Registry provides three API interfaces:

  1. Python API - Fluent interface for Python applications
  2. C++ API - Header-only library for C++ applications
  3. REST API - HTTP/JSON API with OpenAPI/Swagger documentation

Table of Contents


Python API

Installation

# From source
cd python/
pip install .

# Development mode
pip install -e .

# With dev dependencies
pip install -e ".[dev]"

Quick Start

from audiolab_registry import AudioLabRegistry

# Connect to registry
registry = AudioLabRegistry('/path/to/registry.db')

# Get a module
module = registry.get('svf_filter', '1.0.0')
print(f"{module.name} - {module.description}")

# Search
results = (registry.search()
    .category('FILTER')
    .level('L1_ATOM')
    .cpu_cycles_max(100)
    .execute())

# Get dependencies
deps = registry.dependencies('my_module', recursive=True)

# Close connection
registry.close()

Context Manager

with AudioLabRegistry('/path/to/registry.db') as registry:
    module = registry.get('svf_filter')
    # Connection automatically closed

Search API

The search API uses a fluent builder pattern:

results = (registry.search()
    # Filters
    .category('FILTER')              # Filter by category
    .level('L1_ATOM')                # Filter by level
    .tag('analog-modeled')           # Filter by tag
    .cpu_cycles_max(100)             # Max CPU cycles

    # Full-text search
    .search('state-variable')        # Search name/description

    # Performance data
    .with_performance()              # Include performance metrics

    # Sorting
    .order_by('cpu_cycles_per_sample')  # Order by field

    # Pagination
    .paginate(page=1, page_size=20)  # Paginate results

    # Execute
    .execute())

# Access results
for result in results.results:
    print(f"{result['name']} - {result['cpu_cycles_per_sample']} cycles")

print(f"Total: {results.total_count}")

Dependency API

# Direct dependencies
deps = registry.dependencies('module_name', recursive=False)

# Transitive dependencies
all_deps = registry.dependencies('module_name', recursive=True)

# Reverse dependencies
dependents = registry.dependents('module_name')

# Build order (topological sort)
order = registry.build_order(['module_a', 'module_b', 'module_c'])

# Check for cycles
has_cycle = registry.has_cycle(['module_a', 'module_b'])

Performance API

# Get performance metrics
perf = registry.performance('svf_filter')
print(f"CPU: {perf['cpu_cycles_per_sample']}")
print(f"Memory: {perf['memory_kb']} KB")

# Compare two modules
comparison = registry.compare_performance('module_a', 'module_b')
print(f"CPU difference: {comparison['cpu_cycles_diff_percent']:.1f}%")

Statistics API

stats = registry.stats()
print(f"Total modules: {stats['total_modules']}")
print(f"Categories: {stats['categories']}")

# By level
for level, count in stats['by_level'].items():
    print(f"{level}: {count}")

C++ API

Installation

cd cpp/
mkdir build && cd build
cmake ..
make
sudo make install

CMake Integration

find_package(AudioLabRegistry REQUIRED)

add_executable(my_app main.cpp)
target_link_libraries(my_app AudioLab::audiolab_registry)

Quick Start

#include <audiolab_registry.hpp>

using namespace audiolab;

int main() {
    // Connect to registry
    Registry registry("path/to/registry.db");

    // Get a module
    auto module = registry.get("svf_filter", "1.0.0");
    if (module) {
        std::cout << module->name << " - " << module->description << "\n";
    }

    // Search
    auto results = registry.search()
        .category("FILTER")
        .level("L1_ATOM")
        .cpuCyclesMax(100)
        .execute();

    for (const auto& module : results.modules) {
        std::cout << module.name << "\n";
    }

    // Get dependencies
    auto deps = registry.dependencies("my_module");

    return 0;
}

Search API

auto results = registry.search()
    // Filters
    .category("FILTER")
    .level("L1_ATOM")
    .tag("analog-modeled")
    .cpuCyclesMax(100)

    // Full-text search
    .search("state-variable")

    // Sorting
    .orderBy("cpu_cycles_per_sample")

    // Pagination
    .paginate(1, 20)

    // Execute
    .execute();

// Access results
for (const auto& module : results.modules) {
    std::cout << module.name << " - ";
    if (module.cpu_cycles_per_sample) {
        std::cout << *module.cpu_cycles_per_sample << " cycles";
    }
    std::cout << "\n";
}

Dependency API

// Get dependencies
auto deps = registry.dependencies("module_name");

// Get performance
auto perf = registry.performance("svf_filter");
if (perf && perf->cpu_cycles_per_sample) {
    std::cout << "CPU: " << *perf->cpu_cycles_per_sample << "\n";
}

// Get statistics
auto stats = registry.stats();
std::cout << "Total modules: " << stats.total_modules << "\n";

REST API

Starting the Server

cd rest/

# Install dependencies
pip install -r requirements.txt

# Run server
python app.py

# Or with uvicorn
uvicorn app:app --reload --host 0.0.0.0 --port 8000

Docker Deployment

cd rest/
docker build -t audiolab-registry-api .
docker run -p 8000:8000 -v /path/to/registry.db:/app/registry.db audiolab-registry-api

API Documentation

Once the server is running:

Endpoints

Module Endpoints

# Get specific module
GET /modules/{name}?version=1.0.0

# List all modules
GET /modules?level=L1_ATOM&category=FILTER&limit=100

Search Endpoints

# Quick search (GET)
GET /search/quick?q=filter&category=FILTER&limit=20

# Advanced search (POST)
POST /search
{
  "category": "FILTER",
  "level": "L1_ATOM",
  "cpu_cycles_max": 100,
  "tags": ["analog-modeled"],
  "order_by": "cpu_cycles_per_sample",
  "page": 1,
  "page_size": 20
}

Dependency Endpoints

# Get dependencies
GET /dependencies/{module_name}?recursive=true

# Get dependents (reverse dependencies)
GET /dependents/{module_name}

# Calculate build order
POST /build-order
["module_a", "module_b", "module_c"]

Performance Endpoints

# Get performance metrics
GET /performance/{module_name}

# Compare two modules
GET /performance/compare/{module_a}/{module_b}

Statistics Endpoints

# Get registry statistics
GET /stats

cURL Examples

# Get module
curl http://localhost:8000/modules/svf_filter?version=1.0.0

# Search
curl -X POST http://localhost:8000/search \
  -H "Content-Type: application/json" \
  -d '{
    "category": "FILTER",
    "level": "L1_ATOM",
    "cpu_cycles_max": 100,
    "page": 1,
    "page_size": 10
  }'

# Get dependencies
curl http://localhost:8000/dependencies/my_module?recursive=true

# Compare performance
curl http://localhost:8000/performance/compare/svf_filter/biquad_filter

# Get stats
curl http://localhost:8000/stats

Python Requests Examples

import requests

BASE_URL = "http://localhost:8000"

# Get module
response = requests.get(f"{BASE_URL}/modules/svf_filter", params={"version": "1.0.0"})
module = response.json()

# Search
search_params = {
    "category": "FILTER",
    "level": "L1_ATOM",
    "cpu_cycles_max": 100,
    "page": 1,
    "page_size": 20
}
response = requests.post(f"{BASE_URL}/search", json=search_params)
results = response.json()

# Get dependencies
response = requests.get(f"{BASE_URL}/dependencies/my_module", params={"recursive": True})
deps = response.json()

JavaScript/TypeScript Example

const BASE_URL = 'http://localhost:8000';

// Get module
const response = await fetch(`${BASE_URL}/modules/svf_filter?version=1.0.0`);
const module = await response.json();

// Search
const searchResponse = await fetch(`${BASE_URL}/search`, {
  method: 'POST',
  headers: {'Content-Type': 'application/json'},
  body: JSON.stringify({
    category: 'FILTER',
    level: 'L1_ATOM',
    cpu_cycles_max: 100,
    page: 1,
    page_size: 20
  })
});
const results = await searchResponse.json();

Common Patterns

Pattern 1: Find Efficient Modules

# Python
efficient = (registry.search()
    .cpu_cycles_max(50)
    .order_by('cpu_cycles_per_sample')
    .limit(10)
    .execute())
// C++
auto efficient = registry.search()
    .cpuCyclesMax(50)
    .orderBy("cpu_cycles_per_sample")
    .limit(10)
    .execute();
# REST
curl -X POST http://localhost:8000/search -H "Content-Type: application/json" \
  -d '{"cpu_cycles_max": 50, "order_by": "cpu_cycles_per_sample", "page_size": 10}'

Pattern 2: Build Order Calculation

# Python
modules_to_build = ['reverb_engine', 'eq_engine', 'compressor_engine']
build_order = registry.build_order(modules_to_build)
# Returns: dependencies first, then requested modules
# REST
curl -X POST http://localhost:8000/build-order \
  -H "Content-Type: application/json" \
  -d '["reverb_engine", "eq_engine", "compressor_engine"]'

Pattern 3: Performance Comparison

# Python
comparison = registry.compare_performance('svf_filter', 'biquad_filter')
if comparison['cpu_cycles_diff_percent'] > 0:
    print(f"biquad_filter is {comparison['cpu_cycles_diff_percent']:.1f}% slower")
else:
    print(f"biquad_filter is {abs(comparison['cpu_cycles_diff_percent']):.1f}% faster")

Performance

Indexing

The registry uses SQLite FTS5 for full-text search:

  • FTS5 index: Fast text search in module names, descriptions, and tags
  • B-tree indexes: Efficient filtering on category, level, cpu_cycles
  • Materialized views: Pre-computed statistics

Query Optimization

Tips for fast queries:

  1. Use specific filters first: category(), level() before tag()
  2. Limit results: Always use .limit() or .paginate()
  3. Avoid recursive dependencies: Use recursive=False when possible
  4. Cache results: Store frequently accessed modules

Benchmarks

On a registry with 10,000 modules:

Operation Time (avg)
Get by name < 1ms
Search (filtered) 2-5ms
Search (full-text) 5-10ms
Direct dependencies < 1ms
Recursive dependencies 10-50ms
Build order (10 modules) 5-15ms
Statistics 10-20ms

Error Handling

Python

from audiolab_registry import AudioLabRegistry

try:
    with AudioLabRegistry('/path/to/registry.db') as registry:
        module = registry.get('nonexistent_module')
        if module is None:
            print("Module not found")

        # Build order with cycle detection
        order = registry.build_order(['module_a', 'module_b'])

except ValueError as e:
    print(f"Validation error: {e}")
except Exception as e:
    print(f"Error: {e}")

REST API

All REST endpoints return standard HTTP status codes:

  • 200: Success
  • 404: Module not found
  • 400: Invalid request (e.g., circular dependency)
  • 500: Server error

Error response format:

{
  "detail": "Module 'xyz' not found"
}

Environment Variables

Python/C++ APIs

  • AUDIOLAB_REGISTRY_DB: Default database path

REST API

  • AUDIOLAB_REGISTRY_DB: Database path
  • AUDIOLAB_API_HOST: Server host (default: 0.0.0.0)
  • AUDIOLAB_API_PORT: Server port (default: 8000)
  • AUDIOLAB_API_CORS_ORIGINS: CORS allowed origins (comma-separated)

Support

  • Documentation: See docs/ folder
  • Examples: See python/example.py, cpp/example.cpp
  • Issues: Report to AudioLab team
  • API Reference: http://localhost:8000/docs (when REST server running)