question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Serialise FORM bodies with pydantic via type annotiations

See original GitHub issue

Description

I started to use FastAPI and enjoyed serialisation of JSON bodies into pydantic models via type annotations and then I passed the form to my request handler and was surprised with AttributeError.

So I re-read the docs about forms and found its behaviour inconsistent with JSON bodies even though probably all code might already support this.

Example

from fastapi import FastAPI, Request, Form
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    another: str


@app.post("/item_form", response_model=Item)
async def find_item(r: Request):
    # current workaround
    form = await r.form()
    item = Item(**form)
    return item


@app.post("/item", response_model=Item)
async def find_item(r: Request, item: Item):
    # JSON Body works nicely
    print(item.name)
    return item


@app.post("/item_form_a", response_model=Item)
async def find_item(item: Item = Form(...)):
    # alternative 1
    # current: 422 Unprocessable Entity
    return item


class ItemForm(BaseModel):
    name: str = Form(...)
    another: str = Form(...)


@app.post("/item_form_b", response_model=ItemForm)
async def find_item(item: ItemForm):
    # alternative 2
    # current: AttributeError and 422 Unprocessable Entity
    print(item.name)
    return item

Motivation

I’m building a slack bot application which receives slash commands from Slack. POST request received from slack is an URL encoded body. https://api.slack.com/web#slack-web-api__basics__post-bodies__url-encoded-bodies

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:12 (5 by maintainers)

github_iconTop GitHub Comments

14reactions
Mausecommented, Sep 1, 2020

Sorry, should have given a full example:

from fastapi.testclient import TestClient
from fastapi import FastAPI, Depends, Form
from pydantic import BaseModel


app = FastAPI()


def form_body(cls):
    cls.__signature__ = cls.__signature__.replace(
        parameters=[
            arg.replace(default=Form(...))
            for arg in cls.__signature__.parameters.values()
        ]
    )
    return cls


@form_body
class Item(BaseModel):
    name: str
    another: str


@app.post('/test', response_model=Item)
def endpoint(item: Item = Depends(Item)):
    return item


tc = TestClient(app)


r = tc.post('/test', data={'name': 'name', 'another': 'another'})

assert r.status_code == 200
assert r.json() == {'name': 'name', 'another': 'another'}
5reactions
ArcLightSlavikcommented, Sep 21, 2020

@1oglop1 Could you close the issue

alt-text

Read more comments on GitHub >

github_iconTop Results From Across the Web

Create custom datatypes using Pydantic module in Python
Here, we are going to demonstrate how can use pydantic to create models along with your custom validations. First, let's discuss the use...
Read more >
pydantic/Lobby - Gitter
I am using sqlalchemy with PhoneNumber filed type when i try to map a model instance to pydantic one. I haven't found solution...
Read more >
Django and Pydantic - TestDriven.io
Pydantic is a Python package for data validation and settings management that's based on Python type hints. It enforces type hints at ...
Read more >
Pydantic Puzzlers II - Inmanta
Pydantic is a library to validate JSON documents and converts them into Python objects, based on Python Type Annotations.
Read more >
Cool Things You Can Do With Pydantic - Medium
Pydantic is a useful library for data parsing and validation. It coerces input types to the declared type (using type hints), ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found