from __future__ import annotations import os from copy import deepcopy from dataclasses import dataclass from typing import Any, List import numpy as np import pandas as pd @dataclass(frozen=True) class RuntimePaths: current_dir: str project_root: str def parse_cors_origins(raw_origins: str) -> List[str]: origins = [origin.strip() for origin in raw_origins.split(",") if origin.strip()] return origins or ["*"] def clone_cache_payload(payload: Any) -> Any: if payload is None or isinstance(payload, (str, int, float, bool)): return payload if isinstance(payload, list): return [clone_cache_payload(item) for item in payload] if isinstance(payload, tuple): return tuple(clone_cache_payload(item) for item in payload) if isinstance(payload, dict): return {clone_cache_payload(key): clone_cache_payload(value) for key, value in payload.items()} if isinstance(payload, set): return {clone_cache_payload(item) for item in payload} try: return deepcopy(payload) except Exception: return payload def make_json_compatible(value: Any) -> Any: if isinstance(value, dict): return {str(key): make_json_compatible(item) for key, item in value.items()} if isinstance(value, (list, tuple, set)): return [make_json_compatible(item) for item in value] if isinstance(value, np.ndarray): return [make_json_compatible(item) for item in value.tolist()] if isinstance(value, np.generic): return make_json_compatible(value.item()) if isinstance(value, pd.Timestamp): return value.isoformat() return value def resolve_runtime_paths( module_file: str, is_frozen: bool, bundle_dir: str, ) -> RuntimePaths: current_dir = os.path.dirname(os.path.abspath(module_file)) if is_frozen: return RuntimePaths(current_dir=bundle_dir, project_root=bundle_dir) return RuntimePaths( current_dir=current_dir, project_root=os.path.dirname(current_dir), )