| .. | ||
| deploy | ||
| src/catalog_api | ||
| API.md | ||
| INDEX.md | ||
| pyproject.toml | ||
| README.md | ||
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)
- Docker network
didi-network(shared with other modules) - At least one other module running (llm-inference, audio, video-analysis, or web)
Quick Start
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_EXTERNAL_URL |
(required, no default) | External base URL for the aggregated OpenAPI spec (e.g. http://10.11.10.42). Service fails to start if unset. |
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:54300 |
Audio API URL |
CATALOG_VIDEO_URL |
(empty) | Video Analysis API URL — empty by default, so video is disabled unless set |
CATALOG_WEB_URL |
http://didiAI-web-api:51100 |
Web API URL |
CATALOG_COMPONENT_TIMEOUT |
10 |
Component request timeout (seconds) |
Example Responses
List Components
curl http://localhost:11000/v1/components | jq
{
"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
curl http://localhost:11000/v1/models | jq
{
"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
curl http://localhost:11000/v1/status | jq
{
"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:
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
# 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
# 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
# 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)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