Spaces:
Sleeping
Sleeping
anoderb
feat: integrate MySQL user login, SQLite configs, AI Center, and dynamic ML hyperparameter tuning
d8fb724 | # config.py — Centralized Configuration using pydantic-settings | |
| from pydantic_settings import BaseSettings | |
| from functools import lru_cache | |
| from typing import Optional | |
| import os | |
| class Settings(BaseSettings): | |
| # Database (support both MYSQL_ prefix and DB_ prefix) | |
| MYSQL_HOST: Optional[str] = None | |
| MYSQL_PORT: Optional[int] = None | |
| MYSQL_DATABASE: Optional[str] = None | |
| MYSQL_USER: Optional[str] = None | |
| MYSQL_PASSWORD: Optional[str] = None | |
| DB_HOST: Optional[str] = None | |
| DB_PORT: Optional[int] = None | |
| DB_NAME: Optional[str] = None | |
| DB_USER: Optional[str] = None | |
| DB_PASSWORD: Optional[str] = None | |
| # API Auth & Configuration | |
| API_PORT: int = 8000 | |
| API_HOST: str = "0.0.0.0" | |
| API_SECRET_KEY: str = "your-random-secret" | |
| JWT_SECRET_KEY: str = "sikomo-daily-scraper-jwt-secret-key-xyz-789" | |
| JWT_ALGORITHM: str = "HS256" | |
| # Default Schedules | |
| DEFAULT_SCHEDULE: str = "0 8 * * *" | |
| DEFAULT_SCHEDULES: str = "0 8 * * *" | |
| # CORS | |
| FRONTEND_URL: str = "http://localhost:3000" | |
| def DATABASE_URL(self) -> str: | |
| # Fallback mappings | |
| host = self.MYSQL_HOST or self.DB_HOST or os.getenv("MYSQL_HOST") or os.getenv("DB_HOST") or "localhost" | |
| port = self.MYSQL_PORT or self.DB_PORT or os.getenv("MYSQL_PORT") or os.getenv("DB_PORT") or 3306 | |
| db = self.MYSQL_DATABASE or self.DB_NAME or os.getenv("MYSQL_DATABASE") or os.getenv("DB_NAME") or "sikomo_db" | |
| user = self.MYSQL_USER or self.DB_USER or os.getenv("MYSQL_USER") or os.getenv("DB_USER") or "root" | |
| password = self.MYSQL_PASSWORD or self.DB_PASSWORD or os.getenv("MYSQL_PASSWORD") or os.getenv("DB_PASSWORD") or "" | |
| return f"mysql+pymysql://{user}:{password}@{host}:{port}/{db}" | |
| class Config: | |
| env_file = ".env" | |
| extra = "ignore" | |
| def get_settings() -> Settings: | |
| return Settings() | |
| class RuntimeConfig: | |
| """Runtime ML Configuration editable via dashboard without server restart.""" | |
| def __init__(self): | |
| self.optuna_trials: int = int(os.getenv("OPTUNA_TRIALS", "30")) | |
| self.model_dir: str = os.getenv("MODEL_DIR", "models") | |
| self.forecast_days: int = int(os.getenv("FORECAST_DAYS", "7")) | |
| self.default_schedules: str = os.getenv("DEFAULT_FORECAST_SCHEDULES", "0 1 * * *") | |
| def to_dict(self) -> dict: | |
| return { | |
| "optuna_trials": self.optuna_trials, | |
| "model_dir": self.model_dir, | |
| "forecast_days": self.forecast_days, | |
| "default_schedules": self.default_schedules | |
| } | |
| def update(self, key: str, value: str): | |
| allowed = { | |
| "optuna_trials": lambda v: setattr(self, "optuna_trials", int(v)), | |
| "model_dir": lambda v: setattr(self, "model_dir", v), | |
| "forecast_days": lambda v: setattr(self, "forecast_days", int(v)), | |
| "default_schedules": lambda v: setattr(self, "default_schedules", v), | |
| } | |
| if key not in allowed: | |
| raise ValueError(f"Key '{key}' tidak diizinkan untuk diubah.") | |
| allowed[key](value) | |
| runtime_config = RuntimeConfig() |