-
From the example given here - https://fastapi.tiangolo.com/tutorial/bigger-applications/ I have this kind of structure.
I would like to read environment variables, when running/deploying my code, and then pass those variables to How do I achieve this? Do I have to use |
Beta Was this translation helpful? Give feedback.
Replies: 8 comments
-
tags is for giving a name and group endpoints in swagger so no it won't help you can use simply I make some use of it here, maybe that can give you some ideas |
Beta Was this translation helpful? Give feedback.
-
@unography I would recommend the use of the from functools import lru_cache
import os
from typing import Optional
from pydantic import BaseSettings
class AppSettings(BaseSettings):
project_name: str = "My API"
debug: bool = False
# Server
server_name: Optional[str]
server_host: Optional[str]
sentry_dsn: Optional[str]
secret_key: bytes = os.urandom(32)
...
class Config:
env_prefix = "" # defaults to 'APP_'; see description in pydantic docs
allow_mutation = False
@lru_cache()
def get_settings() -> AppSettings:
return AppSettings() This way you can basically treat the settings like a singleton by only accessing them via |
Beta Was this translation helpful? Give feedback.
-
I just wanted to add a further approach that you may wish to take. My approach is more similar to Flask and Django; it depends on environment variables mainly for knowing the path of your settings file. I've chosen to use TOML, but you can use YAML or JSON too. My import os
from functools import lru_cache
from typing import Dict, List
import toml
from pydantic import BaseModel
class DatabaseSettings(BaseModel):
host: str
port: int
username: str
password: str
db_name: str
max_connections: int
class JWTSettings(BaseModel):
key: str
session_duration: int
class AuthenticationSettings(BaseModel):
cert_path: str
hosts: List[str]
username: str
password: str
group_access: Dict[str, List[str]]
class Settings(BaseModel):
database: DatabaseSettings
jwt: JWTSettings
authentication: AuthenticationSettings
@lru_cache()
def get_settings() -> Settings:
settings_path = os.environ.get("MYAPP_SETTINGS", "/etc/myapp/myapp-app.toml")
with open(settings_path) as fp:
settings = Settings.parse_obj(toml.load(fp))
return settings It is also easy to point your unit tests to your testing config as long as you don't attempt to use
If you are in a situation where this causes you trouble, you may wrap your app in a if os.path.basename(sys.argv[0]) in ["gunicorn", "uvicorn"]:
app = get_app() This way, importing the Note: In case anyone is unaware, it seems impossible to call a function when running gunicorn or uvicorn like you can with sync workers. As such, the The best way to avoid this problem is to use the Really hope this helps and provides some more ideas which we can develop further together. Cheers |
Beta Was this translation helpful? Give feedback.
-
Thanks everyone for the discussion and help here! Yeah, for the simplest case, you can just use For a more sophisticated case, I would go for |
Beta Was this translation helpful? Give feedback.
-
There are new docs for handling settings here: https://fastapi.tiangolo.com/advanced/settings/ , started by @alexmitelman in #1118 . Now it documents more or less the same example from @dmontagu above 🚀 |
Beta Was this translation helpful? Give feedback.
-
Thanks @tiangolo. The updated documentation looks cool! Is this issue considered as an open question yet? Can we close it? @unography |
Beta Was this translation helpful? Give feedback.
-
Yes, it's solved! |
Beta Was this translation helpful? Give feedback.
@unography I would recommend the use of the
BaseSettings
class in pydantic. Here's a basic example:This way you can basically treat the sett…