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

Breaking change with path parameters when updating to pydantic>=2 from pydantic<2 #11251

Open
9 tasks done
Kludex opened this issue Mar 5, 2024 Discussed in #11250 · 1 comment
Open
9 tasks done
Labels
question Question or problem

Comments

@Kludex
Copy link
Member

Kludex commented Mar 5, 2024

Discussed in #11250

Originally posted by ThirVondukr March 5, 2024

First Check

  • I added a very descriptive title here.
  • I used the GitHub search to find a similar question 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 uuid import UUID

from fastapi import FastAPI

app = FastAPI()


@app.get("/int/{path}")
async def int_(path: int | str):
    return str(type(path))


@app.get("/uuid/{path}")
async def uuid_(path: UUID | str):
    return str(type(path))

Description

With pydantic<2 parameters are correctly parsed as int and UUID if an appropriate string is passed, with pydantic 2 they're always interpreted as str, I presume this will work the same way with all other types that you can pass into path parameters.
I also observed the same behavior with query, so I assume it behaves the same way with all FastAPI parameters (headers, body, etc).

Operating System

Windows

Operating System Details

No response

FastAPI Version

0.110.0

Pydantic Version

1.10.14 / 2.6.3

Python Version

Python 3.11.5

Additional Context

No response

@Kludex Kludex added the question Question or problem label Mar 5, 2024
@H-Plus-Time
Copy link

A workaround for anyone facing this (NB: this assumes availability of typing.Annotated and pydantic.Field):

@app.get("/uuid/{path}")
-async def uuid_(path: UUID | str):
+async def uuid_(path: Annotated[UUID | str, Field(union_mode='left_to_right')]):
    return str(type(path))

Pydantic v2 switched to union_mode='smart' as the default, which in cases like this will always prefer str (since it's an exact type match).

It's also necessary to do this in any dependencies (as far as I can tell, type annotations set on direct path parameters and function parameters of dependencies aren't shared).

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

No branches or pull requests

2 participants