11import secrets
22import warnings
33import os
4- from typing import Annotated , Any , Literal
4+ from typing import Any , Literal
55
66from pydantic import (
77 EmailStr ,
1515from typing_extensions import Self
1616
1717
18- def parse_cors (v : Any ) -> list [str ] | str :
19- if isinstance (v , str ) and not v .startswith ("[" ):
20- return [i .strip () for i in v .split ("," )]
21- elif isinstance (v , list | str ):
22- return v
23- raise ValueError (v )
18+ def parse_cors (origins : Any ) -> list [str ] | str :
19+ # If it's a plain comma-separated string, split it into a list
20+ if isinstance (origins , str ) and not origins .startswith ("[" ):
21+ return [origin .strip () for origin in origins .split ("," )]
22+ # If it's already a list or JSON-style string, just return it
23+ elif isinstance (origins , (list , str )):
24+ return origins
25+ raise ValueError (f"Invalid CORS origins format: { origins !r} " )
2426
2527
2628class Settings (BaseSettings ):
2729 model_config = SettingsConfigDict (
28- # Use top level .env file (one level above ./backend/)
29- env_file = "../.env" ,
30+ # env_file will be set dynamically in get_settings()
3031 env_ignore_empty = True ,
3132 extra = "ignore" ,
3233 )
33- LANGFUSE_PUBLIC_KEY : str
34- LANGFUSE_SECRET_KEY : str
35- LANGFUSE_HOST : str # 🇪🇺 EU region
36- OPENAI_API_KEY : str
34+
3735 API_V1_STR : str = "/api/v1"
3836 SECRET_KEY : str = secrets .token_urlsafe (32 )
3937 # 60 minutes * 24 hours * 1 days = 1 days
4038 ACCESS_TOKEN_EXPIRE_MINUTES : int = 60 * 24 * 1
41- ENVIRONMENT : Literal ["local" , "staging" , "production" ] = "local"
39+ ENVIRONMENT : Literal [
40+ "development" , "testing" , "staging" , "production"
41+ ] = "development"
4242
4343 PROJECT_NAME : str
4444 SENTRY_DSN : HttpUrl | None = None
@@ -84,7 +84,7 @@ def _check_default_secret(self, var_name: str, value: str | None) -> None:
8484 f'The value of { var_name } is "changethis", '
8585 "for security, please change it, at least for deployments."
8686 )
87- if self .ENVIRONMENT == "local" :
87+ if self .ENVIRONMENT in [ "development" , "testing" ] :
8888 warnings .warn (message , stacklevel = 1 )
8989 else :
9090 raise ValueError (message )
@@ -100,4 +100,17 @@ def _enforce_non_default_secrets(self) -> Self:
100100 return self
101101
102102
103- settings = Settings () # type: ignore
103+ def get_settings () -> Settings :
104+ """Get settings with appropriate env file based on ENVIRONMENT."""
105+ environment = os .getenv ("ENVIRONMENT" , "development" )
106+
107+ # Determine env file
108+ env_files = {"testing" : "../.env.test" , "development" : "../.env" }
109+ env_file = env_files .get (environment , "../.env" )
110+
111+ # Create Settings instance with the appropriate env file
112+ return Settings (_env_file = env_file )
113+
114+
115+ # Export settings instance
116+ settings = get_settings ()
0 commit comments