| """Environment-driven application configuration.
|
|
|
| Two model backends are supported:
|
|
|
| Cloud model β a remote OpenAI-compatible API (e.g. gpt-5.4 via a hosted
|
| endpoint). Used as the powerful multimodal backbone for
|
| tasks like audio transcription.
|
|
|
| Local model β a self-hosted model served via SGLang, vLLM, or any
|
| OpenAI-compatible server (e.g. Qwen3.5-2B on localhost).
|
| Used for high-throughput image recognition / classification.
|
|
|
| Both backends expose ``/v1/chat/completions``; the only difference is the
|
| base URL, API key, and model name.
|
| """
|
|
|
| from __future__ import annotations
|
|
|
| import os
|
| from dataclasses import dataclass
|
|
|
|
|
| @dataclass(frozen=True) |
| class Config: |
| server_host: str
|
| server_port: int
|
|
|
|
|
| client_key: str | None
|
|
|
|
|
| cloud_base_url: str
|
| cloud_api_key: str
|
| cloud_model: str
|
|
|
|
|
| local_base_url: str
|
| local_api_key: str
|
| local_model: str
|
|
|
| captcha_retries: int
|
| captcha_timeout: int
|
|
|
| |
| browser_headless: bool |
| browser_timeout: int |
| browser_proxy_url: str | None = None |
|
|
|
|
|
|
| @property
|
| def captcha_base_url(self) -> str:
|
| return self.cloud_base_url
|
|
|
| @property
|
| def captcha_api_key(self) -> str:
|
| return self.cloud_api_key
|
|
|
| @property
|
| def captcha_model(self) -> str:
|
| return self.cloud_model
|
|
|
| @property
|
| def captcha_multimodal_model(self) -> str:
|
| return self.local_model
|
|
|
|
|
| def load_config() -> Config:
|
| return Config(
|
| server_host=os.environ.get("SERVER_HOST", "0.0.0.0"),
|
| server_port=int(os.environ.get("SERVER_PORT", "8000")),
|
| client_key=os.environ.get("CLIENT_KEY", "").strip() or None,
|
|
|
| cloud_base_url=os.environ.get(
|
| "CLOUD_BASE_URL",
|
| os.environ.get("CAPTCHA_BASE_URL", "https://your-openai-compatible-endpoint/v1"),
|
| ),
|
| cloud_api_key=os.environ.get(
|
| "CLOUD_API_KEY",
|
| os.environ.get("CAPTCHA_API_KEY", ""),
|
| ),
|
| cloud_model=os.environ.get(
|
| "CLOUD_MODEL",
|
| os.environ.get("CAPTCHA_MODEL", "gpt-5.4"),
|
| ),
|
|
|
| local_base_url=os.environ.get(
|
| "LOCAL_BASE_URL",
|
| os.environ.get("CAPTCHA_BASE_URL", "http://localhost:30000/v1"),
|
| ),
|
| local_api_key=os.environ.get(
|
| "LOCAL_API_KEY",
|
| os.environ.get("CAPTCHA_API_KEY", "EMPTY"),
|
| ),
|
| local_model=os.environ.get(
|
| "LOCAL_MODEL",
|
| os.environ.get("CAPTCHA_MULTIMODAL_MODEL", "Qwen/Qwen3.5-2B"),
|
| ),
|
| captcha_retries=int(os.environ.get("CAPTCHA_RETRIES", "3")), |
| captcha_timeout=int(os.environ.get("CAPTCHA_TIMEOUT", "30")), |
| browser_headless=os.environ.get("BROWSER_HEADLESS", "true").strip().lower() |
| in {"1", "true", "yes"}, |
| browser_timeout=int(os.environ.get("BROWSER_TIMEOUT", "30")), |
| browser_proxy_url=os.environ.get("BROWSER_PROXY_URL", "").strip() or None, |
| ) |
|
|
|
|
| config = load_config()
|
|
|