Skip to content

Instantly share code, notes, and snippets.

@TomFaulkner
Last active September 5, 2024 18:43
Show Gist options
  • Save TomFaulkner/eeb8028d4afaca35dda85ebe5e7b76ef to your computer and use it in GitHub Desktop.
Save TomFaulkner/eeb8028d4afaca35dda85ebe5e7b76ef to your computer and use it in GitHub Desktop.
FastAPI Form handlng that doesn't suck
# Source https://github.com/fastapi/fastapi/discussions/7268#discussioncomment-6993634
from fastapi import Form
def form_body(cls):
"""
Converts a Pydantic BaseModel into FastAPI Form Body.
Usage:
@form_body
class OItem(BaseModel):
name: str
num: int | None = None
# or
Item = form_body(aq.ClientAvailabilityCreate)
# Do this to not corrupt the original class, or for code generation.
@router.post('/test', response_model=Item)
def endpoint(item: Item = Depends(Item)):
return item
"""
params = []
for arg in cls.__signature__.parameters.values():
arg_type = str(arg).split(":")[1]
new_arg = arg.replace(default=Form(...))
if "Optional" in arg_type: # TODO: make this support new style | None
new_arg = arg.replace(default=Form(None))
params.append(new_arg)
cls.__signature__ = cls.__signature__.replace(parameters=params)
return cls
@TomFaulkner
Copy link
Author

TomFaulkner commented Aug 14, 2024

TODO: Make it work with modern foo: str | None = None typehints.

This is now supported natively in FastAPI 0.113.0. https://fastapi.tiangolo.com/tutorial/request-form-models/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment