What is the best practice for enabling runtime config from command line during fast-api app launch? #8636
-
First Check
Commit to Help
Example Codedef main(args):
model_path = args[1]
model = load_model(model_path)
app = FastAPI()
@app.get("/{item_id}")
def predict_item(item_id: int):
return dict(item_id=item_id, prediction=model(item_id))
uvicorn.run(app)
if __name__ == "__main__":
args = sys.argv
print(args)
main(args)DescriptionHi I just started using FastAPI and I am liking it. However, right now I am creating the I am doing something like the code example above. But I think there must be a better way. I looked at FastAPI docs and I saw app = FastAPI()
@app.get("/{item_id}", model = Depends(something))
def predict_item(item_id: int):
# Somehow get this model properly defined outside of main
return dict(item_id=item_id, prediction=model(item_id))
def main(args):
model_path = args[1]
model = load_model(model_path)
# configure app to use model.
uvicorn.run(app)
if __name__ == "__main__":
args = sys.argv
print(args)
main(args)Also asked this question on Twitter at @FastAPI: https://twitter.com/FastAPI/status/1505619967311499264 Operating SystemLinux Operating System DetailsNo response FastAPI Version0.75.0 Python Version3.7.11 Additional ContextNo response |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments 1 reply
-
|
You could try using environment variables for that. For example: app = FastAPI()
@app.get("/{item_id}", model = Depends(something))
def predict_item(item_id: int):
# Somehow get this model properly defined outside of main
return dict(item_id=item_id, prediction=model(item_id))
def main(args):
model_path = os.environ.get("MODEL_PATH")
model = load_model(model_path)
# configure app to use model.
uvicorn.run(app)
if __name__ == "__main__":
args = sys.argv
main(args) |
Beta Was this translation helpful? Give feedback.
-
|
We use a settings class that has defaults and can be overriden by ENV. import secrets
from pydantic import BaseSettings
class AppSettings(BaseSettings):
TESTING: bool = True
SESSION_SECRET: str = "".join(secrets.choice(string.ascii_letters) for i in range(16)) # noqa: S311
CORS_ORIGINS: str = "*"
CORS_ALLOW_METHODS: List[str] = ["GET", "PUT", "PATCH", "POST", "DELETE", "OPTIONS", "HEAD"]
CORS_ALLOW_HEADERS: List[str] = ["If-None-Match", "Authorization", "If-Match", "Content-Type"]
CORS_EXPOSE_HEADERS: List[str] = [
"Cache-Control",
"Content-Language",
"Content-Length",
"Content-Type",
"Expires",
"Last-Modified",
"Pragma",
"Content-Range",
"ETag",
]
ENVIRONMENT: str = "local"
DATABASE_URI: str = "postgresql://user:pas@localhost/orchestrator-core"
CACHE_HOST: str = "127.0.0.1"
CACHE_PORT: int = 6379
SERVICE_NAME: str = "orchestrator-core"
LOGGING_HOST: str = "localhost"
LOG_LEVEL: str = "DEBUG"
WEBSOCKET_BROADCASTER_URL: str = "memory://"
ENABLE_WEBSOCKETS: bool = True
app_settings = AppSettings() in main.py import app_settings from settings
if app_settings.ENABLE_WEBSOCKETS:
print("Do something with WS")Pydantic ensure that you get validation for you config + the mentioned ENV support. E.g. every parameter can be set via ENV; and will have sensible defaults for development. |
Beta Was this translation helpful? Give feedback.
-
|
Thanks @kheealam and @acidjunk yes I have tried the ENV approach but I was looking for something more configurable via command line args. My current setup allows me to read the command line args but I don't like encapsulating making the app inside a function, hence I was hoping if there was a better way. I like the |
Beta Was this translation helpful? Give feedback.
-
|
I think you could do something by inheriting from BaseSettings and implement CLI overridable defaults there. We use it in a k8s context were everything is configured via ENV vars. |
Beta Was this translation helpful? Give feedback.
-
|
Hi @acidjunk thanks that is very useful. let me give it a shot. |
Beta Was this translation helpful? Give feedback.
-
|
i did something similar related to config file, it load base on the environment |
Beta Was this translation helpful? Give feedback.
Hi @acidjunk thanks that is very useful. let me give it a shot.