mirror of
https://github.com/zvx-echo6/recon.git
synced 2026-05-20 06:34:40 +02:00
feat(navi): deployment profiles + /api/config endpoint
Add profile-driven config infrastructure:
- config/profiles/{home,regional_pi,minimal_pi}.yaml templates
- lib/deployment_config.py loader (reads RECON_PROFILE env var)
- GET /api/config returns active profile as JSON (5min cache)
Frontend reads this on startup to determine tile source, defaults,
and feature flags. No existing behavior changed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
d4c5c371ca
commit
e6b81db520
5 changed files with 149 additions and 0 deletions
10
lib/api.py
10
lib/api.py
|
|
@ -24,6 +24,7 @@ from werkzeug.utils import secure_filename
|
|||
|
||||
from .utils import get_config, content_hash, clean_filename_to_title, derive_source_and_category, generate_download_url, setup_logging
|
||||
from .status import StatusDB
|
||||
from .deployment_config import get_deployment_config
|
||||
|
||||
logger = setup_logging('recon.api')
|
||||
|
||||
|
|
@ -1165,6 +1166,15 @@ def api_knowledge_stats():
|
|||
return jsonify(_cache['knowledge_stats'])
|
||||
|
||||
|
||||
@app.route('/api/config')
|
||||
def api_config():
|
||||
"""Return deployment profile config for frontend consumption."""
|
||||
config = get_deployment_config()
|
||||
resp = jsonify(config)
|
||||
resp.headers['Cache-Control'] = 'public, max-age=300'
|
||||
return resp
|
||||
|
||||
|
||||
@app.route('/api/health')
|
||||
def api_health():
|
||||
"""Health check endpoint for monitoring."""
|
||||
|
|
|
|||
46
lib/deployment_config.py
Normal file
46
lib/deployment_config.py
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
"""
|
||||
Deployment profile loader.
|
||||
|
||||
Reads RECON_PROFILE env var (default: "home"), loads the matching YAML
|
||||
from config/profiles/<profile>.yaml, and caches the parsed dict in memory.
|
||||
Provides get_deployment_config() for use by the /api/config endpoint.
|
||||
"""
|
||||
import os
|
||||
import yaml
|
||||
from .utils import setup_logging
|
||||
|
||||
logger = setup_logging('recon.deployment_config')
|
||||
|
||||
_config_cache = None
|
||||
|
||||
|
||||
def load_deployment_config():
|
||||
"""Load and cache the deployment profile. Called once at import time."""
|
||||
global _config_cache
|
||||
|
||||
profile = os.environ.get('RECON_PROFILE', 'home')
|
||||
config_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'config', 'profiles')
|
||||
config_path = os.path.join(config_dir, f'{profile}.yaml')
|
||||
|
||||
if not os.path.exists(config_path):
|
||||
raise FileNotFoundError(
|
||||
f"Deployment profile '{profile}' not found at {config_path}. "
|
||||
f"Available profiles: {', '.join(f.replace('.yaml','') for f in os.listdir(config_dir) if f.endswith('.yaml'))}"
|
||||
)
|
||||
|
||||
with open(config_path, 'r') as f:
|
||||
_config_cache = yaml.safe_load(f)
|
||||
|
||||
logger.info(f"Loaded deployment profile: {profile} ({_config_cache.get('region_name', 'unknown')})")
|
||||
return _config_cache
|
||||
|
||||
|
||||
def get_deployment_config():
|
||||
"""Return the cached deployment config dict."""
|
||||
if _config_cache is None:
|
||||
load_deployment_config()
|
||||
return _config_cache
|
||||
|
||||
|
||||
# Load on import so startup fails fast if profile is missing
|
||||
load_deployment_config()
|
||||
Loading…
Add table
Add a link
Reference in a new issue