from pathlib import Path from pydantic_settings import BaseSettings, SettingsConfigDict # api/app/config.py -> repo root locally; "/" in the API image, where compose mounts /pipeline. REPO_ROOT = Path(__file__).resolve().parents[2] class Settings(BaseSettings): model_config = SettingsConfigDict(env_file=".env", extra="ignore") database_url: str = "postgresql+asyncpg://rarelens:rarelens@localhost:5432/rarelens" # docker-compose publishes MLflow on 5001; macOS AirPlay Receiver owns 5000. mlflow_tracking_uri: str = "http://localhost:5001" model_name: str = "rarelens-pathogenicity" # Registry alias set by `rarelens_ml.train --register` (stages are deprecated in MLflow 3). model_alias: str = "production" # A model artifact URI (gs://...) scores without an MLflow server running; wins over the registry. model_uri: str | None = None gcs_bucket: str | None = None # set in GCP; local uses ./data pubsub_topic: str | None = None # "vcf-uploaded" in GCP; local runs pipeline inline # Serverless track: run the Nextflow driver as a Cloud Run job instead of Argo + Pub/Sub. cloudrun_job: str | None = None gcp_project: str | None = None # required with pubsub_topic or cloudrun_job gcp_region: str = "europe-west2" pipeline_dir: Path = REPO_ROOT / "pipeline" # Handed to the pipeline when it differs from the API's own: the loader runs inside a # container, where the API's localhost would be the container itself. pipeline_database_url: str | None = None nextflow_profile: str = "docker" # Local (non-gs://) VCFs must live under this directory. local_data_root: Path = Path("/data") # Browsers calling the API cross-origin; behind the ingress the UI is same-origin. cors_origins: list[str] = ["http://localhost:5173"] # Whether to keep pooled database connections open between requests. Set it false on a host # that sleeps idle containers to save money -- Railway's serverless mode decides a service is # idle from its *outbound* traffic, and a held connection is outbound traffic, so a pool keeps # the service awake and billable forever. Costs a connection setup per request, which is # nothing at demo traffic and the wrong trade under real load. database_idle_connections: bool = True settings = Settings()