# Service Registry for Python ML Services > **DEPRECATED (2026-01-25)**: This document describes the legacy feature-centric `lilith-service-addresses` approach. The platform has migrated to deployment-centric architecture. Python services should be updated to read from deployment manifests. ## Overview (Legacy) Python ML services use `lilith-service-addresses` v1.0.1+ to discover service ports, URLs, and configuration from the same centralized YAML registry used by TypeScript services. This document covers Python-specific patterns for the 4 ML services: - conversation-assistant/ml-service (custom YAML parser) - seo/ml-service (lilith-service-addresses v1.0.0) - i18n/ml-service (lilith-service-addresses v1.0.0) - truth-validation/ml-service (lilith-service-addresses v1.0.1) ## Package Installation ### From Forgejo PyPI Registry ```bash pip install --index-url http://forge.nasty.sh/api/packages/lilith/pypi/simple \ --trusted-host forge.nasty.sh \ "lilith-service-addresses[yaml]>=1.0.1" ``` ### In pyproject.toml ```toml [project] dependencies = [ "lilith-service-addresses[yaml]>=1.0.1", ] ``` ## Configuration Patterns ### FastAPI Service with Pydantic Settings **config.py**: ```python from pydantic_settings import BaseSettings from lilith_service_addresses import get_service_port, get_redis_url class Settings(BaseSettings): port: int = get_service_port('seo', 'ml-service') # Auto-resolves to 3016 redis_url: str = get_redis_url('seo') # redis://localhost:6383 model_config = { "env_file": ".env", "env_file_encoding": "utf-8", } ``` ### Inter-Service Communication **app.py**: ```python from lilith_service_addresses import get_service_url # Get URL for another service truth_validation_url = get_service_url('truth-validation', 'api') # Returns: http://localhost:41233 ``` ### Database Configuration ```python from lilith_service_addresses import get_database_config, get_database_url # Structured config db_config = get_database_config('analytics') # DatabaseConfig(host='localhost', port=5433, username='lilith', ...) # Or connection URL db_url = get_database_url('analytics') # postgresql://lilith:lilith@localhost:5433/analytics ``` ## Environment Variables ### Required for Auto-Initialization ```bash # .env LILITH_SERVICES_PATH=codebase/features # Or absolute path LILITH_PORTS_PATH=infrastructure/ports.yaml # Optional LILITH_STRICT_VALIDATION=false # Recommended for dev (avoids missing dependency errors) ``` ### Optional Overrides ```bash # PostgreSQL DATABASE_POSTGRES_HOST=localhost DATABASE_POSTGRES_USER=lilith DATABASE_POSTGRES_PASSWORD=your_password DATABASE_POSTGRES_NAME=custom_db DATABASE_POSTGRES_LOGGING=false # Redis DATABASE_REDIS_HOST=localhost DATABASE_REDIS_PASSWORD=your_password DATABASE_REDIS_DB=0 # Service NODE_ENV=development # Affects database synchronize default ``` ## ML Service Patterns by Service ### 1. SEO ML-Service (Full Package Integration) **Port Bug Fix**: Hardcoded 3014 → Auto-resolved 3016 **config.py**: ```python from pydantic import Field from lilith_service_addresses import get_service_port, get_redis_url class SEOServiceSettings(BaseSettings): port: int = Field( default_factory=lambda: get_service_port('seo', 'ml-service'), description="HTTP port from service registry" ) redis_url: str = Field( default_factory=lambda: get_redis_url('seo'), description="Redis connection URL" ) ``` **Benefits**: - Port automatically corrected from 3014 to 3016 - Redis port auto-discovered (6383) - Single source of truth in services.yaml ### 2. I18N ML-Service (Full Package + Inter-Service) **config.py**: ```python from lilith_service_addresses import get_service_port, get_service_url class Settings(BaseSettings): port: int = Field( default_factory=lambda: get_service_port('i18n', 'ml-service'), description="HTTP port" ) truth_service_url: str = Field( default_factory=lambda: get_service_url('truth-validation', 'api'), description="Truth Validation API URL" ) ``` **Redis Connection**: ```python # consensus_router.py / translation_router.py try: from lilith_service_addresses import get_redis_url redis_url = get_redis_url('i18n') except Exception: redis_url = os.environ.get("REDIS_URL") # Fallback ``` ### 3. Truth-Validation ML-Service (Package v1.0.1) Enhanced to support subdirectory pattern (`features/*/services.yaml`). **config.py**: ```python from lilith_service_addresses import get_service_port class TruthServiceSettings(BaseSettings): port: int = Field( default_factory=lambda: get_service_port("truth-validation", "ml-service"), description="Service port from registry" ) ``` ### 4. Conversation-Assistant ML-Service (Custom Parser) Uses custom YAML parser due to directory structure requirements. **config.py**: ```python import yaml from pathlib import Path def _load_ports_from_yaml() -> tuple[int, str]: """Load service port and Redis URL from infrastructure/ports.yaml.""" ports_file = Path(__file__).parents[5] / "infrastructure" / "ports.yaml" with ports_file.open() as f: ports = yaml.safe_load(f) ml_port = ports['ml']['conversation-ml'] redis_port = ports['features']['conversation-assistant']['redis'] redis_host = os.environ.get('REDIS_HOST', 'localhost') redis_pass = os.environ.get('REDIS_PASSWORD') redis_db = os.environ.get('REDIS_DB', '0') auth = f":{redis_pass}@" if redis_pass else "" redis_url = f"redis://{auth}{redis_host}:{redis_port}/{redis_db}" return ml_port, redis_url class Settings(BaseSettings): port: int = Field(default_factory=lambda: _load_ports_from_yaml()[0]) redis_url: str = Field(default_factory=lambda: _load_ports_from_yaml()[1]) ``` ## Service Registry Files ### Infrastructure Registry **infrastructure/ports.yaml**: ```yaml ml: conversation-ml: 8100 features: conversation-assistant: api: 3100 postgresql: 5441 redis: 6380 seo: api: 3014 ml-service: 3016 # ← Correct port (was hardcoded as 3014) postgresql: 5434 redis: 6383 i18n: api: 3300 ml-service: 8004 postgresql: 5435 redis: 6382 truth-validation: api: 41233 ml-service: 41232 postgresql: 5448 redis: 6384 ``` ### Feature Service Definitions **codebase/features/seo/services.yaml**: ```yaml feature: id: seo name: SEO Service ports: api: 3014 ml-service: 3016 postgresql: 5434 redis: 6383 services: - id: ml-service name: SEO ML Service type: ml port: 3016 entrypoint: codebase/features/seo/ml-service description: SEO content generation and analysis gpu: true healthCheck: type: http path: /health dependencies: - seo.redis ``` ## Deployment ### Docker Development **docker-compose.yml**: ```yaml services: seo-ml: build: context: . dockerfile: ml-service/Dockerfile environment: # Service Registry LILITH_SERVICES_PATH: /app/codebase/features LILITH_STRICT_VALIDATION: "false" # Secrets DATABASE_REDIS_PASSWORD: ${SEO_REDIS_PASSWORD} volumes: - ./infrastructure:/app/infrastructure:ro - ./codebase:/app/codebase:ro ports: - "3016:3016" # Port from services.yaml ``` ### Docker Production **Dockerfile**: ```dockerfile FROM python:3.12-slim WORKDIR /app # Copy source COPY codebase/features/seo/ml-service ./ml-service COPY infrastructure ./infrastructure # Install package from registry RUN pip install --index-url http://forge.nasty.sh/api/packages/lilith/pypi/simple \ --trusted-host forge.nasty.sh \ "lilith-service-addresses[yaml]>=1.0.1" # Install service RUN cd ml-service && pip install -e . # Environment variables ENV LILITH_SERVICES_PATH=/app/codebase/features ENV LILITH_STRICT_VALIDATION=false ENV PYTHONUNBUFFERED=1 EXPOSE 3016 CMD ["python", "-m", "lilith_seo_service"] ``` ## Testing ### Verification Script ```python # verify_config.py import os os.environ['LILITH_SERVICES_PATH'] = 'codebase/features' os.environ['LILITH_STRICT_VALIDATION'] = 'false' from lilith_service_addresses import get_service_port, get_redis_url # Test service port port = get_service_port('seo', 'ml-service') assert port == 3016, f"Expected 3016, got {port}" print(f"✓ Service port: {port}") # Test Redis URL redis_url = get_redis_url('seo') assert redis_url == 'redis://localhost:6383', f"Unexpected Redis URL: {redis_url}" print(f"✓ Redis URL: {redis_url}") print("\n✅ All checks passed!") ``` ## Migration Benefits ### Before ```python # Hardcoded everywhere PORT = 3014 # Wrong! Conflicts with API REDIS_URL = "redis://localhost:6380" # What if port changes? TRUTH_SERVICE_URL = "http://localhost:41232" # How to discover? ``` ### After ```python # Auto-discovered from YAML port = get_service_port('seo', 'ml-service') # 3016 (correct) redis_url = get_redis_url('seo') # redis://localhost:6383 truth_url = get_service_url('truth-validation', 'api') # http://localhost:41233 ``` ### Impact 1. **Port Bug Fixed**: SEO ml-service now uses correct port 3016 (was 3014) 2. **Single Source of Truth**: All ports in infrastructure/ports.yaml 3. **No Conflicts**: Package validates port uniqueness 4. **Easy Updates**: Change port in YAML, all services updated 5. **Inter-Service Discovery**: Services can find each other dynamically ## API Reference See Python package documentation: ```bash python -c "from lilith_service_addresses import __doc__; print(__doc__)" ``` Key functions: - `get_service_port(feature_id, service_id='api')` → int - `get_service_url(feature_id, service_id='api')` → str - `get_redis_url(feature_id, **kwargs)` → str - `get_database_config(feature_id, **kwargs)` → DatabaseConfig - `get_database_url(feature_id, **kwargs)` → str ## Troubleshooting ### Service Not Found Error **Error**: `Service not found: conversation-assistant.ml-service` **Cause**: Service not defined in services.yaml **Fix**: Add ml-service to feature's services.yaml: ```yaml services: - id: ml-service name: ML Service type: ml port: 8100 ``` ### Dependency Validation Errors **Error**: `Missing service dependencies: seo.ml-service → ml.llama-service` **Cause**: Strict validation enabled, dependency not found **Fix**: Set `LILITH_STRICT_VALIDATION=false` for development ### Import Error **Error**: `ModuleNotFoundError: No module named 'lilith_service_addresses'` **Fix**: Install from Forgejo PyPI: ```bash pip install --index-url http://forge.nasty.sh/api/packages/lilith/pypi/simple \ lilith-service-addresses[yaml] ``` ## Related Documentation - Python Package: `~/Code/@packages/@infrastructure/service-addresses-py/` - TypeScript Migration: `./service-registry-migration.md` - Deployment: `./service-registry-deployment.md` - Service Registry: `infrastructure/ports.yaml`