# Catalog API **Service catalog and discovery** - aggregates component information from all ML services. ## What It Does This module provides a unified API to discover and query all available ML services, models, and endpoints in the system. It aggregates `/v1/info` from all registered components and exposes: - Component metadata (resources) - Available models across all services - Available functions/endpoints - Health status of all components ## Prerequisites **Required:** - All global prerequisites (see main [README.md](../../README.md)) - Docker network `deploy_default` (shared with other modules) - At least one other module running (llm-inference, audio, video-analysis, or web) ## Quick Start ```bash cd deploy/ # Start the catalog API docker compose up -d # Check health curl http://localhost:11000/health # List all components curl http://localhost:11000/v1/components | jq # List all models curl http://localhost:11000/v1/models | jq # Get component status curl http://localhost:11000/v1/status | jq ``` ## API Endpoints | Endpoint | Method | Description | |----------|--------|-------------| | `/health` | GET | Health check | | `/v1/components` | GET | List all components with full metadata | | `/v1/components/{component_id}` | GET | Get specific component info | | `/v1/models` | GET | List all available models | | `/v1/functions` | GET | List all available functions/endpoints | | `/v1/status` | GET | Aggregated health status | | `/v1/openapi` | GET | Aggregated OpenAPI 3.1.0 spec (all components) | | `/v1/docs` | GET | Swagger UI for aggregated API | | `/v1/redoc` | GET | ReDoc for aggregated API | | `/v1/openapi/component/{component_id}` | GET | OpenAPI spec for a single component | ## Configuration Configure via environment variables (prefix: `CATALOG_`): | Variable | Default | Description | |----------|---------|-------------| | `CATALOG_HOST` | `0.0.0.0` | Server host | | `CATALOG_PORT` | `11000` | Server port (Production API Gateway: 11000) | | `CATALOG_LOG_LEVEL` | `INFO` | Log level | | `CATALOG_LLM_URL` | `http://didiAI-llm-api:14011` | LLM Inference API URL | | `CATALOG_AUDIO_URL` | `http://didiAI-audio-api:54300` | Audio API URL | | `CATALOG_VIDEO_URL` | `http://didiAI-video-api:54600` | Video Analysis API URL | | `CATALOG_WEB_URL` | `http://didiAI-web-api:51100` | Web API URL | | `CATALOG_COMPONENT_TIMEOUT` | `10` | Component request timeout (seconds) | ## Example Responses ### List Components ```bash curl http://localhost:11000/v1/components | jq ``` ```json { "components": [ { "component_id": "llm-inference", "base_url": "http://didiAI-llm-api:14011", "resource": { "name": "LLM Inference Gateway", "slug": "llm-inference", "resource_type": "api_service", ... }, "models": [...], "functions": [...] }, { "component_id": "audio-transcription", ... } ], "total": 4, "errors": null } ``` ### List All Models ```bash curl http://localhost:11000/v1/models | jq ``` ```json { "models": [ { "name": "Qwen3.5-35B-A3B", "slug": "qwen3.5", "provider": "vllm", "model_type": "llm", "component_id": "llm-inference", "component_name": "LLM Inference Gateway", ... }, { "name": "Whisper large-v3-turbo", "component_id": "audio-transcription", ... } ], "total": 5 } ``` ### Component Status ```bash curl http://localhost:11000/v1/status | jq ``` ```json { "status": "healthy", "components": [ { "component_id": "llm-inference", "url": "http://didiAI-llm-api:14011", "reachable": true, "healthy": true, "status_code": 200 }, { "component_id": "audio-transcription", "reachable": true, "healthy": true, "status_code": 200 } ], "healthy_count": 4, "total_count": 4 } ``` ## Use Cases ### 1. Backend System Integration Your backend can pull all service metadata and populate the database: ```python import requests # Pull all components response = requests.get("http://localhost:11000/v1/components") components = response.json()["components"] for comp in components: # Populate catalog.resources db.insert_resource(comp["resource"]) # Populate catalog.models for model in comp.get("models", []): db.insert_model(model) # Populate catalog.functions for function in comp.get("functions", []): db.insert_function(function) ``` ### 2. Service Discovery ```python # Find all vision models response = requests.get("http://localhost:11000/v1/models") models = response.json()["models"] vision_models = [m for m in models if m["model_type"] == "vision"] print(f"Found {len(vision_models)} vision models") ``` ### 3. Health Monitoring ```python # Check system health response = requests.get("http://localhost:11000/v1/status") status = response.json() if status["status"] != "healthy": alert(f"System degraded: {status['healthy_count']}/{status['total_count']} healthy") ``` ## Architecture ``` +-----------------------------------------------------+ | Catalog API (11000) | | - Aggregates /v1/info from all components | | - No database, just HTTP aggregation | | - Read-only, no writes | +----------------+------------------------------------+ | +-----------+-----------+-----------+ v v v v +--------+ +---------+ +--------+ +----------+ | LLM | | Audio | | Video | | Web | | 14011 | | 54300 | | 54600 | | 51100 | +--------+ +---------+ +--------+ +----------+ ``` ## Development ```bash # Install dependencies uv sync # Run locally (requires components running) uv run python -m uvicorn catalog_api.app:app --host 0.0.0.0 --port 11000 # Test curl http://localhost:11000/v1/components | jq ``` ## Dependencies on Other Modules This module aggregates information from: - `llm-inference` (port 14011, Docker internal: didiAI-llm-api) - `audio` (port 54300, Docker internal: didiAI-audio-api) - `video-analysis` (port 54600, Docker internal: didiAI-video-api) - `web` (port 51100, Docker internal: didiAI-web-api) **Note:** The catalog API can function with partial availability. If a component is unavailable, it will be skipped with a warning in the logs. ## License MIT