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

openapi.json throws error when generated with nested models #3782

Closed
9 tasks done
yeus opened this issue Aug 28, 2021 · 12 comments
Closed
9 tasks done

openapi.json throws error when generated with nested models #3782

yeus opened this issue Aug 28, 2021 · 12 comments

Comments

@yeus
Copy link

yeus commented Aug 28, 2021

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.

Commit to Help

  • I commit to help with one of those options 👆

Example Code

from typing import List, Dict, Tuple

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Answers(BaseModel):
    answers: Dict[str, List[Tuple[str, float]]] = {}

@app.get("/qa", response_model=Answers)
async def qatask(request: str):
    return Answers()

if __name__ == "__main__":
    import uvicorn
    uvicorn.run("bugfind:app", host="0.0.0.0", port=5000, reload=True,
                workers=1)  # , debug=True)

Description

open http://localhost:5000/docs or http://localhost:5000/openapi.json and you will see the error in the logs.

Operating System

Linux

Operating System Details

ubuntu 20.04

FastAPI Version

0.68.1

Python Version

3.8.10

Additional Context

There was a bug #383 a while ago reporting the same problem but closed. This new issue here is in order to reopen that bug as it still isn't solved or reappeared since then. Fell free to close this new issue and reopen the old bug if that is preferred.

this is the error:

Traceback (most recent call last):
  File "//home/name/.local/lib/python3.8/site-packages/uvicorn/protocols/http/h11_impl.py", line 373, in run_asgi
    result = await app(self.scope, self.receive, self.send)
  File "//home/name/.local/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py", line 75, in __call__
    return await self.app(scope, receive, send)
  File "//home/name/.local/lib/python3.8/site-packages/fastapi/applications.py", line 208, in __call__
    await super().__call__(scope, receive, send)
  File "//home/name/.local/lib/python3.8/site-packages/starlette/applications.py", line 112, in __call__
    await self.middleware_stack(scope, receive, send)
  File "//home/name/.local/lib/python3.8/site-packages/starlette/middleware/errors.py", line 181, in __call__
    raise exc from None
  File "//home/name/.local/lib/python3.8/site-packages/starlette/middleware/errors.py", line 159, in __call__
    await self.app(scope, receive, _send)
  File "//home/name/.local/lib/python3.8/site-packages/starlette/exceptions.py", line 82, in __call__
    raise exc from None
  File "//home/name/.local/lib/python3.8/site-packages/starlette/exceptions.py", line 71, in __call__
    await self.app(scope, receive, sender)
  File "//home/name/.local/lib/python3.8/site-packages/starlette/routing.py", line 580, in __call__
    await route.handle(scope, receive, send)
  File "//home/name/.local/lib/python3.8/site-packages/starlette/routing.py", line 241, in handle
    await self.app(scope, receive, send)
  File "//home/name/.local/lib/python3.8/site-packages/starlette/routing.py", line 52, in app
    response = await func(request)
  File "//home/name/.local/lib/python3.8/site-packages/fastapi/applications.py", line 161, in openapi
    return JSONResponse(self.openapi())
  File "//home/name/.local/lib/python3.8/site-packages/fastapi/applications.py", line 136, in openapi
    self.openapi_schema = get_openapi(
  File "//home/name/.local/lib/python3.8/site-packages/fastapi/openapi/utils.py", line 410, in get_openapi
    return jsonable_encoder(OpenAPI(**output), by_alias=True, exclude_none=True)  # type: ignore
  File "pydantic/main.py", line 406, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 4 validation errors for OpenAPI
components -> schemas -> Answers -> properties -> answers -> additionalProperties -> items -> items
  value is not a valid dict (type=type_error.dict)
components -> schemas -> Answers -> properties -> answers -> additionalProperties -> $ref
  field required (type=value_error.missing)
components -> schemas -> Answers -> properties -> answers -> additionalProperties
  value could not be parsed to a boolean (type=type_error.bool)
components -> schemas -> Answers -> $ref
  field required (type=value_error.missing)
@yeus yeus added the question Question or problem label Aug 28, 2021
@Nicholas-Schaub
Copy link

Reposting my response from the closed issue that yeus linked to so it doesn't go overlooked:

I have similar code structure to @yeus and also am running into this issue. I only have issues with response_model values that have nested iterable types (i.e. List, Tuple, Dict). I did some additional testing that made me think this was a Windows vs Linux issue, but upon further investigation I found that something became broken in the most recent version of fastapi.

This code will generate proper documentation when using fastapi[standard]==0.65.2 but does not generate proper documentation in fastapi[standard]==0.68.1.

# Obviously skipping some imports

class DataResponse(BaseModel):
    data: typing.List[int]
    limits: typing.List[typing.Tuple[float,float]]
    counts: typing.Tuple[int,int]

@app.post("/bins",
          status_code=status.HTTP_200_OK,
          tags=["data"],
          response_model=DataResponse)
def bins(input: DataSelection):

    return None

if __name__ == "__main__":
    import uvicorn

    uvicorn.run("server:app", host="127.0.0.1", port=8001, log_level="info")

When the above is run using fastapi[standard]==0.65.2, I can access documentation at 127.0.0.1:8001/docs.

When the above is run using fastapi[standard]==0.68.1, I receive the following error:

  File "pydantic\main.py", line 406, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 3 validation errors for OpenAPI
components -> schemas -> DataResponse -> properties -> limits -> items -> items
  value is not a valid dict (type=type_error.dict)
components -> schemas -> DataResponse -> properties -> counts -> items
  value is not a valid dict (type=type_error.dict)
components -> schemas -> DataResponse -> $ref
  field required (type=value_error.missing)

For now, I am just downgrading fastapi so that documentation works.

@Nicholas-Schaub
Copy link

I should note that I also tested on both Windows and Linux, and I get the same results regardless of OS.

@tonybaloney
Copy link

Hitting the same issue, here is a reproducible example

from typing import List, Tuple

from fastapi import FastAPI
from pydantic import BaseModel


class GeoJson2DPoint(BaseModel):
    type: str = "Point"
    coordinates: Tuple[float, float] = (0.0, 0.0)


class Address(BaseModel):
    street_number: int
    street_name: str
    city: str
    country: str
    geo: GeoJson2DPoint
    postal_code: str


app = FastAPI()


@app.get("/places", response_model=List[Address])
async def get_addresses() -> List[Address]:
    ...

@chen-kay
Copy link

Try to change Tuple to fixed type like str, int.

@tonybaloney
Copy link

Try to change Tuple to fixed type like str, int.

Yes, If you comment out the coordinates field, or change the type to a non-collection, the error goes away

@Nicholas-Schaub
Copy link

I can also verify that commenting out the coordinates field, or changing to a plain iterator (i.e. List, Tuple, etc) fixes the problem in the latest version. However, this does not permit the type checking I want nor the data structures I wish to show in the documentation.

This is clearly a bug that was introduced between 0.65.2 and 0.68.1. I'm sure a simple diff will help locate it.

@tonybaloney
Copy link

I reckon its this change 97fa743

@tonybaloney
Copy link

Related PR #3628

Cc @tiangolo

@HansBrende
Copy link

@tonybaloney @yeus this seems to be related to #3665 (possibly a duplicate?)

@Nicholas-Schaub
Copy link

@HansBrende This definitely appears to be a duplicate. I had seen this error in a previous duplicate, but it looked like it had been fixed, and then reintroduced again.

@tiangolo
Copy link
Member

It seems this is a duplicate of #3665

In short, it should be fixed by FastAPI 0.73.0, released in the next hours. 🎉

For more info, read the last comment in that issue: #3665 (comment)

And the comment in the PR: #3874 (comment)

@github-actions
Copy link
Contributor

github-actions bot commented Feb 3, 2022

Assuming the original need was handled, this will be automatically closed now. But feel free to add more comments or create new issues or PRs.

@github-actions github-actions bot closed this as completed Feb 3, 2022
@tiangolo tiangolo changed the title [BUG] openapi.json throws error when generated with nested models openapi.json throws error when generated with nested models Feb 24, 2023
@tiangolo tiangolo reopened this Feb 27, 2023
@fastapi fastapi locked and limited conversation to collaborators Feb 27, 2023
@tiangolo tiangolo converted this issue into discussion #6561 Feb 27, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Projects
None yet
Development

No branches or pull requests

6 participants