Files

1 line
4.7 KiB
JSON

{"repo": "bolecodex/changdu-skills", "files": {"changdu/src/changdu/config.py": {"b2d4e868980143d41ccf8b368af02131f093822e": {"t": 1785674278.9071984, "n": 4330, "h": "255c5b76c92febfe", "c": "\"\"\"Configuration loading with precedence controls.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nfrom dataclasses import dataclass\nfrom pathlib import Path\nfrom typing import Any\n\nimport tomllib\n\nfrom changdu.errors import ConfigError\n\n\nDEFAULT_CONFIG_PATH = Path.home() / \".config\" / \"changdu\" / \"config.toml\"\nDEFAULT_TRAJECTORY_DIR = Path.home() / \".local\" / \"share\" / \"changdu\" / \"runs\"\n\n\n@dataclass\nclass AppConfig:\n api_key: str\n base_url: str = \"https://ark.cn-beijing.volces.com\"\n image_endpoint: str = \"/api/v3/images/generations\"\n video_submit_endpoint: str = \"/api/v3/contents/generations/tasks\"\n video_status_endpoint_template: str = \"/api/v3/contents/generations/tasks/{task_id}\"\n # `*_model` fields can be regular model IDs or user-owned endpoint IDs (ep-*)\n text_model: str | None = None\n image_model: str = \"doubao-seedream-5-0-260128\"\n video_model: str = \"doubao-seedance-2-0-260128\"\n image_size: str = \"2K\"\n video_ratio: str = \"16:9\"\n video_duration: int = 15\n request_timeout_s: int = 120\n poll_interval_s: int = 10\n poll_max_wait_s: int = 900\n trajectory_dir: Path = DEFAULT_TRAJECTORY_DIR\n\n\ndef _read_toml(path: Path) -> dict[str, Any]:\n if not path.exists():\n return {}\n with path.open(\"rb\") as f:\n return tomllib.load(f)\n\n\ndef _profile_map(data: dict[str, Any], profile: str) -> dict[str, Any]:\n profiles = data.get(\"profiles\", {})\n selected = profiles.get(profile, {})\n default_section = data.get(\"default\", {})\n merged = {**default_section, **selected}\n return merged\n\n\ndef load_config(\n *,\n profile: str = \"default\",\n config_path: Path | None = None,\n overrides: dict[str, Any] | None = None,\n) -> AppConfig:\n path = config_path or DEFAULT_CONFIG_PATH\n data = _read_toml(path)\n cfg_map = _profile_map(data, profile)\n overrides = overrides or {}\n\n api_key = (\n overrides.get(\"api_key\")\n or os.getenv(\"CHANGDU_ARK_API_KEY\")\n or os.getenv(\"ARK_API_KEY\")\n or cfg_map.get(\"api_key\")\n )\n if not api_key:\n raise ConfigError(\n \"Missing API key. Set CHANGDU_ARK_API_KEY (or ARK_API_KEY), or configure api_key in profile.\"\n )\n\n merged: dict[str, Any] = {\n \"api_key\": api_key,\n \"base_url\": os.getenv(\"CHANGDU_ARK_BASE_URL\", cfg_map.get(\"base_url\", \"https://ark.cn-beijing.volces.com\")),\n \"image_endpoint\": cfg_map.get(\"image_endpoint\", \"/api/v3/images/generations\"),\n \"video_submit_endpoint\": cfg_map.get(\"video_submit_endpoint\", \"/api/v3/contents/generations/tasks\"),\n \"video_status_endpoint_template\": cfg_map.get(\n \"video_status_endpoint_template\", \"/api/v3/contents/generations/tasks/{task_id}\"\n ),\n \"text_model\": (\n os.getenv(\"CHANGDU_SEED_TEXT_ENDPOINT\")\n or os.getenv(\"CHANGDU_TEXT_MODEL\")\n or cfg_map.get(\"text_model\")\n ),\n \"image_model\": (\n os.getenv(\"CHANGDU_SEEDREAM_ENDPOINT\")\n or os.getenv(\"CHANGDU_IMAGE_MODEL\")\n or cfg_map.get(\"image_model\", \"doubao-seedream-5-0-260128\")\n ),\n \"video_model\": (\n os.getenv(\"CHANGDU_SEEDANCE_ENDPOINT\")\n or os.getenv(\"CHANGDU_VIDEO_MODEL\")\n or cfg_map.get(\"video_model\", \"doubao-seedance-2-0-260128\")\n ),\n \"image_size\": cfg_map.get(\"image_size\", \"2K\"),\n \"video_ratio\": cfg_map.get(\"video_ratio\", \"16:9\"),\n \"video_duration\": int(cfg_map.get(\"video_duration\", 15)),\n \"request_timeout_s\": int(\n os.getenv(\"CHANGDU_REQUEST_TIMEOUT_S\")\n or cfg_map.get(\"request_timeout_s\", 120)\n ),\n \"poll_interval_s\": int(\n os.getenv(\"CHANGDU_POLL_INTERVAL_S\")\n or cfg_map.get(\"poll_interval_s\", 10)\n ),\n \"poll_max_wait_s\": int(\n os.getenv(\"CHANGDU_POLL_MAX_WAIT_S\")\n or cfg_map.get(\"poll_max_wait_s\", 900)\n ),\n \"trajectory_dir\": Path(\n os.getenv(\"CHANGDU_TRAJECTORY_DIR\", cfg_map.get(\"trajectory_dir\", str(DEFAULT_TRAJECTORY_DIR)))\n ),\n }\n merged.update({k: v for k, v in overrides.items() if v is not None})\n if isinstance(merged.get(\"trajectory_dir\"), str):\n merged[\"trajectory_dir\"] = Path(merged[\"trajectory_dir\"])\n return AppConfig(**merged)\n"}}}}