File size: 3,503 Bytes
317d1fd
45df059
 
317d1fd
 
 
28471a4
 
 
 
 
 
 
 
 
 
317d1fd
28471a4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1fda7a5
45df059
 
 
 
1fda7a5
45df059
 
260a069
 
 
 
 
2a0dea8
 
 
 
 
 
 
 
 
 
 
260a069
2a0dea8
260a069
 
2a0dea8
 
 
 
 
 
 
 
45df059
1fda7a5
45df059
 
 
 
1fda7a5
45df059
 
260a069
 
 
 
45df059
 
317d1fd
86b116d
317d1fd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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()
            
            # Detect if running on HF Spaces
            self.is_hf_space = bool(os.getenv("SPACE_ID"))
            
            # API tokens
            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")
            
            # API endpoints
            self.hf_api_url = self._sanitize_url(os.getenv("HF_API_ENDPOINT_URL", "https://api-inference.huggingface.co/v1/"))
            
            # Fallback settings
            self.use_fallback = os.getenv("USE_FALLBACK", "true").lower() == "true"
            
            # Local model configuration
            self.local_model_name = os.getenv("LOCAL_MODEL_NAME", "mistral:latest")
            self.ollama_host = self._sanitize_url(os.getenv("OLLAMA_HOST", ""))
            
            # OpenWeather API
            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 ""
            
        # Remove leading/trailing whitespace and control characters
        url = url.strip()
        # Remove any newlines, carriage returns, tabs, and null bytes
        url = re.sub(r'[\r\n\t\0\x0b\x0c]+', '', url)
        # Remove any trailing URL encoding artifacts
        url = url.rstrip('%0a').rstrip('%0d')
        
        # Handle the specific case where environment variable name is included
        if 'hf_api_endpoint_url=' in url.lower():
            # Extract the actual URL part
            url = url.split('=')[-1]
        
        # Remove any protocol prefix issues
        url = url.replace('hf_api_endpoint_url=', '')
        url = url.replace('HF_API_ENDPOINT_URL=', '')
        
        # Ensure proper URL format
        if url and not url.startswith(('http://', 'https://')):
            # Check if it looks like a domain
            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
        
        # Remove double slashes (but keep ://)
        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 ""
            
        # Remove leading/trailing whitespace and control characters
        host = host.strip()
        # Remove any newlines, carriage returns, tabs, and null bytes
        host = re.sub(r'[\r\n\t\0\x0b\x0c]+', '', host)
        # Remove any trailing URL encoding artifacts
        host = host.rstrip('%0a').rstrip('%0d')
        
        return host

# Global config instance
config = Config()