|
import os |
|
import re |
|
import urllib.parse |
|
from dotenv import load_dotenv |
|
|
|
class Config: |
|
"""Singleton configuration class with thread-safe implementation""" |
|
|
|
_instance = None |
|
_initialized = False |
|
|
|
def __new__(cls): |
|
if cls._instance is None: |
|
cls._instance = super(Config, cls).__new__(cls) |
|
return cls._instance |
|
|
|
def __init__(self): |
|
if not self._initialized: |
|
load_dotenv() |
|
|
|
|
|
self.is_hf_space = bool(os.getenv("SPACE_ID")) |
|
|
|
|
|
self.hf_token = os.getenv("HF_TOKEN") |
|
self.openai_api_key = os.getenv("OPENAI_API_KEY") |
|
self.nasa_api_key = os.getenv("NASA_API_KEY") |
|
|
|
|
|
self.hf_api_url = self._sanitize_url(os.getenv("HF_API_ENDPOINT_URL", "https://api-inference.huggingface.co/v1/")) |
|
|
|
|
|
self.use_fallback = os.getenv("USE_FALLBACK", "true").lower() == "true" |
|
|
|
|
|
self.local_model_name = os.getenv("LOCAL_MODEL_NAME", "mistral:latest") |
|
self.ollama_host = self._sanitize_url(os.getenv("OLLAMA_HOST", "")) |
|
|
|
|
|
self.openweather_api_key = os.getenv("OPENWEATHER_API_KEY") |
|
|
|
self._initialized = True |
|
|
|
def _sanitize_url(self, url: str) -> str: |
|
"""Sanitize URL by removing whitespace and control characters""" |
|
if not url: |
|
return "" |
|
|
|
|
|
url = url.strip() |
|
|
|
url = re.sub(r'[\r\n\t\0\x0b\x0c]+', '', url) |
|
|
|
url = url.rstrip('%0a').rstrip('%0d') |
|
|
|
|
|
if 'hf_api_endpoint_url=' in url.lower(): |
|
|
|
url = url.split('=')[-1] |
|
|
|
|
|
url = url.replace('hf_api_endpoint_url=', '') |
|
url = url.replace('HF_API_ENDPOINT_URL=', '') |
|
|
|
|
|
if url and not url.startswith(('http://', 'https://')): |
|
|
|
if re.match(r'^[a-zA-Z0-9.-]+(?:\.[a-zA-Z]{2,})+', url) or 'huggingface.cloud' in url: |
|
url = 'https://' + url |
|
else: |
|
url = 'https://' + url |
|
|
|
|
|
if '://' in url: |
|
protocol, rest = url.split('://', 1) |
|
rest = re.sub(r'//+', '/', rest) |
|
url = protocol + '://' + rest |
|
|
|
return url |
|
|
|
def _sanitize_host(self, host: str) -> str: |
|
"""Sanitize host by removing whitespace and control characters""" |
|
if not host: |
|
return "" |
|
|
|
|
|
host = host.strip() |
|
|
|
host = re.sub(r'[\r\n\t\0\x0b\x0c]+', '', host) |
|
|
|
host = host.rstrip('%0a').rstrip('%0d') |
|
|
|
return host |
|
|
|
|
|
config = Config() |
|
|