feat(01-08): add env field to AppSettings, RuntimeConfig alias, and YAML config overlays

- Add env: Literal["jetson", "x86_dev", "ci", "sitl"] = "x86_dev" to AppSettings
- Expose RuntimeConfig = AppSettings alias for pipeline consumers
- Implement settings_customise_sources for YamlConfigSettingsSource overlay
- Create config/{x86_dev,jetson,ci,sitl}.yaml with env-specific defaults
- Add pyyaml>=6.0 to pyproject.toml dependencies
This commit is contained in:
Yuzviak
2026-05-11 09:02:14 +03:00
parent 35b2e98fad
commit 275f18d0e3
6 changed files with 39 additions and 1 deletions
+1
View File
@@ -0,0 +1 @@
env: ci
+1
View File
@@ -0,0 +1 @@
env: jetson
+1
View File
@@ -0,0 +1 @@
env: sitl
+1
View File
@@ -0,0 +1 @@
env: x86_dev
+1
View File
@@ -19,6 +19,7 @@ dependencies = [
"opencv-python-headless>=4.9,<4.11", # 4.11+ requires numpy>=2.0 (incompatible with GTSAM) "opencv-python-headless>=4.9,<4.11", # 4.11+ requires numpy>=2.0 (incompatible with GTSAM)
"gtsam>=4.3a0", "gtsam>=4.3a0",
"pymavlink>=2.4", "pymavlink>=2.4",
"pyyaml>=6.0",
] ]
[project.optional-dependencies] [project.optional-dependencies]
+34 -1
View File
@@ -3,9 +3,10 @@
from __future__ import annotations from __future__ import annotations
from pathlib import Path from pathlib import Path
from typing import Literal
from pydantic import Field from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict from pydantic_settings import BaseSettings, SettingsConfigDict, YamlConfigSettingsSource
class DatabaseConfig(BaseSettings): class DatabaseConfig(BaseSettings):
@@ -162,6 +163,8 @@ class AppSettings(BaseSettings):
extra="ignore", extra="ignore",
) )
env: Literal["jetson", "x86_dev", "ci", "sitl"] = "x86_dev"
db: DatabaseConfig = Field(default_factory=DatabaseConfig) db: DatabaseConfig = Field(default_factory=DatabaseConfig)
api: APIConfig = Field(default_factory=APIConfig) api: APIConfig = Field(default_factory=APIConfig)
tiles: TileProviderConfig = Field(default_factory=TileProviderConfig) tiles: TileProviderConfig = Field(default_factory=TileProviderConfig)
@@ -174,6 +177,36 @@ class AppSettings(BaseSettings):
satellite: SatelliteConfig = Field(default_factory=SatelliteConfig) satellite: SatelliteConfig = Field(default_factory=SatelliteConfig)
eskf: ESKFSettings = Field(default_factory=ESKFSettings) eskf: ESKFSettings = Field(default_factory=ESKFSettings)
@classmethod
def settings_customise_sources(cls, settings_cls, **kwargs):
"""Load YAML overlay from config/{env}.yaml when present."""
import os
import yaml
init_kwargs = kwargs.get("init_settings")
env_settings = kwargs.get("env_settings")
dotenv = kwargs.get("dotenv_settings")
file_secret = kwargs.get("file_secret_settings")
# Determine which env we're in (check ENV env-var before loading YAML)
current_env = os.environ.get("ENV", "x86_dev")
yaml_path = Path(f"config/{current_env}.yaml")
yaml_source = None
if yaml_path.exists():
try:
yaml_source = YamlConfigSettingsSource(settings_cls, yaml_file=yaml_path)
except Exception:
yaml_source = None
sources = [s for s in [init_kwargs, env_settings, dotenv, file_secret] if s is not None]
if yaml_source is not None:
sources.append(yaml_source)
return tuple(sources)
# Alias for external consumers that expect RuntimeConfig
RuntimeConfig = AppSettings
_settings: AppSettings | None = None _settings: AppSettings | None = None