Skip to content
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

Support tuples in model roots #1870

Closed
9 tasks done
Mause opened this issue Aug 10, 2020 · 4 comments
Closed
9 tasks done

Support tuples in model roots #1870

Mause opened this issue Aug 10, 2020 · 4 comments
Labels
question Question or problem question-migrate

Comments

@Mause
Copy link
Contributor

Mause commented Aug 10, 2020

First check

  • I added a very descriptive title to this issue.
  • I used the GitHub search to find a similar issue and didn't find it.
  • I searched the FastAPI documentation, with the integrated search.
  • I already searched in Google "How to X in FastAPI" and didn't find any information.
  • I already read and followed all the tutorial in the docs and didn't find an answer.
  • I already checked if it is not related to FastAPI but to Pydantic.
  • I already checked if it is not related to FastAPI but to Swagger UI.
  • I already checked if it is not related to FastAPI but to ReDoc.
  • After submitting this, I commit to:
    • Read open issues with questions until I find 2 issues where I can help someone and add a comment to help there.
    • Or, I already hit the "watch" button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.
    • Implement a Pull Request for a confirmed bug.

Example

Here's a self-contained minimal, reproducible, example with my use case:

from fastapi import FastAPI
from pprint import pprint
from fastapi.testclient import TestClient
from typing import Tuple, Dict, List
from pydantic import BaseModel

app = FastAPI()


class TupleModel(BaseModel):
    __root__: Tuple[int, str]


class DictModel(BaseModel):
    __root__: Dict[str, str]


class ListModel(BaseModel):
    __root__: List[str]


@app.get('/', response_model=TupleModel)
def get(l: ListModel, d: DictModel):
    return TupleModel([1, ''])


print(TupleModel.schema_json())  # works
print(DictModel.schema_json())  # works
print(ListModel.schema_json())  # works
print(app.openapi())  # breaks
{"title": "TupleModel", "type": "array", "items": [{"type": "integer"}, {"type": "string"}]}
{"title": "DictModel", "type": "object", "additionalProperties": {"type": "string"}}
{"title": "ListModel", "type": "array", "items": {"type": "string"}}
Traceback (most recent call last):
  File "test_tuple.py", line 30, in <module>
    print(app.openapi())
  File "/home/me/.local/share/virtualenvs/rarbg_local-S8att4rT/lib/python3.8/site-packages/fastapi/applications.py", line 105, in openapi
    self.openapi_schema = get_openapi(
  File "/home/me/.local/share/virtualenvs/rarbg_local-S8att4rT/lib/python3.8/site-packages/fastapi/openapi/utils.py", line 372, in get_openapi
    return jsonable_encoder(OpenAPI(**output), by_alias=True, exclude_none=True)
  File "pydantic/main.py", line 346, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 2 validation errors for OpenAPI
components -> schemas -> TupleModel -> items
  value is not a valid dict (type=type_error.dict)
components -> schemas -> TupleModel -> $ref
  field required (type=value_error.missing)

Description

  • Ideally this would be supported in fastapi as it in pydantic

If you're happy to see this fixed, I can (attempt to) raise a pr to fix it myself

@Mause Mause added the feature New feature or request label Aug 10, 2020
@Koschi13
Copy link

Hey @Mause how is it going? Have you already tried to fix it?

@ycd
Copy link
Contributor

ycd commented Oct 24, 2020

Just found this is related to #466, as @tiangolo says

tuples with exact values inside are explicitly unsupported by OpenAPI

I do not think we can implement this, but I could not find that part in the OpenAPI specification either.

@PrettyWood
Copy link
Contributor

I think this will be doable once #3038 is merged. With 3.1 any JSON schema will be valid. And with pydantic/pydantic#2497 the generated tuple schema should be the expected one

@tiangolo tiangolo added question Question or problem reviewed question-migrate and removed feature New feature or request labels Feb 24, 2023
@tiangolo
Copy link
Owner

tiangolo commented Mar 4, 2023

Tuples are supported directly in FastAPI, but not with the __root__ trick, as FastAPI uses and encourages the annotations directly, and it can handle them directly, because internally it creates Pydantic fields for each parameter. Nevertheless, OpenAPI and the current version of Swagger UI don't support showing them in the docs, so yeah, that doesn't work.

The latest version of OpenAPI, based on the latest JSON Schema, does support them, but Swagger UI still doesn't support that version.

Pydantic v2 will come with the latest JSON Schema, and FastAPI will support the latest OpenAPI using it, although doing some tricks, probably declaring it as a previous version, to make Swagger UI keep rendering the rest (while they make a release that supports the latest versions).

This is gonna be updated with the update to Pydantic v2, but without __root__ fields, instead, using type annotations directly.

Given that I'll close this issue to clean up things, as this is mainly a drawback of Swagger UI. But still, soon with Pydantic v2 and the latest OpenAPI (with overridden tricks for the version, to convince Swagger UI) we'll have a way to do this.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Question or problem question-migrate
Projects
None yet
Development

No branches or pull requests

5 participants