Fastapi: [QUESTION] Cannot specify encoding style for object and array elements

Created on 2 Jun 2019  路  6Comments  路  Source: tiangolo/fastapi

Describe the bug
OpenAPI defines a number of encoding styles for complex types like arrays and objects, and specifically reccomends using them for things like form data encoding. While the underlying OpenAPI models for parameters appear to support this, using them does not affect the resulting OpenAPI definition.

from fastapi import FastAPI, Form, Query
from pydantic import BaseModel
from typing import List

api = FastAPI()

@api.post('/list_form.json')
def test_list_form(
    id: int = Form(...),
    list: List[str] = Form(..., style = 'spaceDelimited', explode=False)
):
    pass

@api.get('/list_query.json')
def test_list_query(
    id: int = Query(...),
    list: List[str] = Query(..., style = 'spaceDelimited', explode=False)
):
    pass

class ObjectType(BaseModel):
    foo: int
    bar: int
    baz: str

@api.post('/obj_form.json')
def test_obj_form(
    id: int = Form(...),
    obj: ObjectType = Form(..., style = 'deepObject', explode=True)
):
    pass

This also prevents more complex object encodings from being used for query parameters, which some API standards may require.

from fastapi import FastAPI, Form, Query
from pydantic import BaseModel
from typing import List

api = FastAPI()

class ObjectType(BaseModel):
    foo: int
    bar: int
    baz: str


@api.post('/obj_form.json')
def test_obj_form(
    id: int = Form(...),
    obj: ObjectType = Form(..., style = 'deepObject', explode=True)
):
    pass
  File ".pyenv/lib/python3.7/site-packages/fastapi/dependencies/utils.py", line 187, in get_dependant
    ), f"Param: {param_field.name} can only be a request body, using Body(...)"
AssertionError: Param: obj can only be a request body, using Body(...)

Expected behavior
All parameter types provided by FastAPI should support parameter encoding and schema encoding where applicable, as specified by the OpenAPI specification. If consistency is to be taken into account, adding keywords parameter for style, explode and allowReserved would probably be ideal. An alternative syntax for path variables and possibly query variables has been proposed before (see #268), but concerns have already been raised about the ergonomics of this solution, not to mention that it would not cover the other parameter types and having both solutions could prove to be a source of bugs and confusion for everyone.

Environment:

  • OS: Linux
  • FastAPI Version : 0.27

    • Python version: 3.7

question

All 6 comments

This is currently not supported.

FastAPI generates valid OpenAPI schemas that cover a very wide range of APIs, and a wide amount of what is described in the spec, but it doesn't necessarily have a way to specify absolutely everything described in the OpenAPI spec, still, the API schemas generated are OpenAPI valid.

I think this is the same you wrote in #268 , right?

I think this is the same you wrote in #268 , right?

I realized afterwards that this was trying to push a solution (and one with a good number of pitfalls, at that) to a problem that hadn't been clearly stated yet, hence why I decided to open this second issue as a bug (now a question) instead of a feature request. This issue was meant to somewhat subsume or replace #268.

This is currently not supported.

FastAPI generates valid OpenAPI schemas that cover a very wide range of APIs, and a wide amount of what is described in the spec, but it doesn't necessarily have a way to specify absolutely everything described in the OpenAPI spec, still, the API schemas generated are OpenAPI valid.

Yeah, I've been looking into the whole FastAPI stack and code these past few weeks, and it's clear now that this should probably be raised as a Pydantic issue before reporting it here.

I'll close this issue now as I think this would be more or less a corner case, with quite some extra complexity.

But if you still need to implement some sophisticate extra features like these for your use case, it's now possible to subclass and override the APIRouter, and then you could also subclass Query, Form, etc. That way you can extend everything to suit your needs.

https://fastapi.tiangolo.com/tutorial/custom-request-and-route/

@tiangolo: I understand, it really is a very niche corner case. I was just attempting to use FastAPI to replicate existing APIs, and that came up as an unsupported feature that could have proved useful. If you're designing your own API from scratch, though, I would agree that the usefulness of this would be pretty limited. I'll be sure to look into custom routers and Query parameters.

Thank you.

We are migrating to FastAPI and has a requirement of keeping compatibility with current API docs and actual API, where we are receiving comma-delimited string and have the server auto-explode into string list.

It would be nice if FastAPI's way of declaring Query has an extension for that. At the moment, we would have to do validation on request manually and add the schema for explode: false type of query parameter also manually.

@lephuongbg: samuelcolvin/pydantic#1848 adds something akin to what you're describing to Pydantic, but support would need to be added to FastAPI for it to be properly exposed in the generated API documentation, I believe.

@tiangolo: As the author of the PR I mentioned, do you think FastAPI could benefit from an integration with these as far as parameter typing is concerned?

Was this page helpful?
0 / 5 - 0 ratings