Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot specify encoding style for object and array elements #283

Closed
sm-Fifteen opened this issue Jun 2, 2019 · 7 comments
Closed

Cannot specify encoding style for object and array elements #283

sm-Fifteen opened this issue Jun 2, 2019 · 7 comments
Labels
question Question or problem question-migrate

Comments

@sm-Fifteen
Copy link
Contributor

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
@sm-Fifteen sm-Fifteen added the bug Something isn't working label Jun 2, 2019
@tiangolo tiangolo added question Question or problem and removed bug Something isn't working labels Jun 28, 2019
@tiangolo tiangolo changed the title [BUG] Cannot specify encoding style for object and array elements [QUESTION] Cannot specify encoding style for object and array elements Jun 28, 2019
@tiangolo
Copy link
Owner

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?

@sm-Fifteen
Copy link
Contributor Author

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.

@tiangolo
Copy link
Owner

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/

@sm-Fifteen
Copy link
Contributor Author

@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.

@lephuongbg
Copy link

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.

@sm-Fifteen
Copy link
Contributor Author

@lephuongbg: pydantic/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?

@tiangolo
Copy link
Owner

tiangolo commented Nov 9, 2022

Right now Pydantic v2 is about to be released, that will include a bunch of features, and I want to update several things related to that here in FastAPI. Not sure what would be the effort and complexity involved in supporting this, but maybe we can check it again after that, maybe there's a way to achieve it, but I'll have to do the other things first.

Sorry for the long delay! 🙈 I wanted to personally address each issue/PR and they piled up through time, but now I'm checking each one in order.

@tiangolo tiangolo changed the title [QUESTION] Cannot specify encoding style for object and array elements Cannot specify encoding style for object and array elements Feb 24, 2023
@tiangolo tiangolo reopened this Feb 28, 2023
Repository owner locked and limited conversation to collaborators Feb 28, 2023
@tiangolo tiangolo converted this issue into discussion #8322 Feb 28, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
question Question or problem question-migrate
Projects
None yet
Development

No branches or pull requests

3 participants