From aeb9f4bb854d030803e2d13cdb64dd0bc5843f00 Mon Sep 17 00:00:00 2001 From: Sofie Van Landeghem Date: Mon, 23 Mar 2026 13:36:49 +0100 Subject: [PATCH 01/15] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Increase=20lower=20b?= =?UTF-8?q?ound=20to=20`pydantic=20>=3D2.9.0.`=20and=20fix=20the=20test=20?= =?UTF-8?q?suite=20(#15139)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com> --- .github/workflows/test.yml | 3 ++ pyproject.toml | 4 +- tests/test_schema_compat_pydantic_v2.py | 67 ++++++++++++++++++------- tests/test_union_body_discriminator.py | 59 ++++++++++++++++------ uv.lock | 4 +- 5 files changed, 100 insertions(+), 37 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2e39633a0c..e852e0f25d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -102,6 +102,9 @@ jobs: uv.lock - name: Install Dependencies run: uv sync --no-dev --group tests --extra all + - name: Ensure that we have the lowest supported Pydantic version + if: matrix.uv-resolution == 'lowest-direct' + run: uv pip install "pydantic==2.9.0" - name: Install Starlette from source if: matrix.starlette-src == 'starlette-git' run: uv pip install "git+https://github.com/Kludex/starlette@main" diff --git a/pyproject.toml b/pyproject.toml index 73d3929292..612d8a0d8a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,7 +43,7 @@ classifiers = [ ] dependencies = [ "starlette>=0.46.0", - "pydantic>=2.7.0", + "pydantic>=2.9.0", "typing-extensions>=4.8.0", "typing-inspection>=0.4.2", "annotated-doc>=0.0.2", @@ -156,7 +156,7 @@ docs-tests = [ ] github-actions = [ "httpx >=0.27.0,<1.0.0", - "pydantic >=2.5.3,<3.0.0", + "pydantic >=2.9.0,<3.0.0", "pydantic-settings >=2.1.0,<3.0.0", "pygithub >=2.3.0,<3.0.0", "pyyaml >=5.3.1,<7.0.0", diff --git a/tests/test_schema_compat_pydantic_v2.py b/tests/test_schema_compat_pydantic_v2.py index 737687f256..7612c6ab5b 100644 --- a/tests/test_schema_compat_pydantic_v2.py +++ b/tests/test_schema_compat_pydantic_v2.py @@ -1,4 +1,5 @@ import pytest +from dirty_equals import IsOneOf from fastapi import FastAPI from fastapi.testclient import TestClient from inline_snapshot import snapshot @@ -63,28 +64,58 @@ def test_openapi_schema(client: TestClient): } }, "components": { - "schemas": { - "PlatformRole": { - "type": "string", - "enum": ["admin", "user"], - "title": "PlatformRole", + "schemas": IsOneOf( + # Pydantic >= 2.11: no top-level OtherRole + { + "PlatformRole": { + "type": "string", + "enum": ["admin", "user"], + "title": "PlatformRole", + }, + "User": { + "properties": { + "username": {"type": "string", "title": "Username"}, + "role": { + "anyOf": [ + {"$ref": "#/components/schemas/PlatformRole"}, + {"enum": [], "title": "OtherRole"}, + ], + "title": "Role", + }, + }, + "type": "object", + "required": ["username", "role"], + "title": "User", + }, }, - "User": { - "properties": { - "username": {"type": "string", "title": "Username"}, - "role": { - "anyOf": [ - {"$ref": "#/components/schemas/PlatformRole"}, - {"enum": [], "title": "OtherRole"}, - ], - "title": "Role", + # Pydantic < 2.11: adds a top-level OtherRole schema + { + "OtherRole": { + "enum": [], + "title": "OtherRole", + }, + "PlatformRole": { + "type": "string", + "enum": ["admin", "user"], + "title": "PlatformRole", + }, + "User": { + "properties": { + "username": {"type": "string", "title": "Username"}, + "role": { + "anyOf": [ + {"$ref": "#/components/schemas/PlatformRole"}, + {"enum": [], "title": "OtherRole"}, + ], + "title": "Role", + }, }, + "type": "object", + "required": ["username", "role"], + "title": "User", }, - "type": "object", - "required": ["username", "role"], - "title": "User", }, - } + ) }, } ) diff --git a/tests/test_union_body_discriminator.py b/tests/test_union_body_discriminator.py index 1b682c7751..53350abc06 100644 --- a/tests/test_union_body_discriminator.py +++ b/tests/test_union_body_discriminator.py @@ -1,5 +1,6 @@ from typing import Annotated, Any, Literal +from dirty_equals import IsOneOf from fastapi import FastAPI from fastapi.testclient import TestClient from inline_snapshot import snapshot @@ -88,11 +89,19 @@ def test_discriminator_pydantic_v2() -> None: "description": "Successful Response", "content": { "application/json": { - "schema": { - "type": "object", - "additionalProperties": True, - "title": "Response Save Union Body Discriminator Items Post", - } + "schema": IsOneOf( + # Pydantic < 2.11: no additionalProperties + { + "type": "object", + "title": "Response Save Union Body Discriminator Items Post", + }, + # Pydantic >= 2.11: has additionalProperties + { + "type": "object", + "additionalProperties": True, + "title": "Response Save Union Body Discriminator Items Post", + }, + ) } }, }, @@ -114,11 +123,21 @@ def test_discriminator_pydantic_v2() -> None: "schemas": { "FirstItem": { "properties": { - "value": { - "type": "string", - "const": "first", - "title": "Value", - }, + "value": IsOneOf( + # Pydantic >= 2.10: const only + { + "type": "string", + "const": "first", + "title": "Value", + }, + # Pydantic 2.9: const + enum + { + "type": "string", + "const": "first", + "enum": ["first"], + "title": "Value", + }, + ), "price": {"type": "integer", "title": "Price"}, }, "type": "object", @@ -140,11 +159,21 @@ def test_discriminator_pydantic_v2() -> None: }, "OtherItem": { "properties": { - "value": { - "type": "string", - "const": "other", - "title": "Value", - }, + "value": IsOneOf( + # Pydantic >= 2.10.0: const only + { + "type": "string", + "const": "other", + "title": "Value", + }, + # Pydantic 2.9.x: const + enum + { + "type": "string", + "const": "other", + "enum": ["other"], + "title": "Value", + }, + ), "price": {"type": "number", "title": "Price"}, }, "type": "object", diff --git a/uv.lock b/uv.lock index 096b0a361c..90e9b4e462 100644 --- a/uv.lock +++ b/uv.lock @@ -1252,7 +1252,7 @@ requires-dist = [ { name = "jinja2", marker = "extra == 'all'", specifier = ">=3.1.5" }, { name = "jinja2", marker = "extra == 'standard'", specifier = ">=3.1.5" }, { name = "jinja2", marker = "extra == 'standard-no-fastapi-cloud-cli'", specifier = ">=3.1.5" }, - { name = "pydantic", specifier = ">=2.7.0" }, + { name = "pydantic", specifier = ">=2.9.0" }, { name = "pydantic-extra-types", marker = "extra == 'all'", specifier = ">=2.0.0" }, { name = "pydantic-extra-types", marker = "extra == 'standard'", specifier = ">=2.0.0" }, { name = "pydantic-extra-types", marker = "extra == 'standard-no-fastapi-cloud-cli'", specifier = ">=2.0.0" }, @@ -1350,7 +1350,7 @@ docs-tests = [ ] github-actions = [ { name = "httpx", specifier = ">=0.27.0,<1.0.0" }, - { name = "pydantic", specifier = ">=2.5.3,<3.0.0" }, + { name = "pydantic", specifier = ">=2.9.0,<3.0.0" }, { name = "pydantic-settings", specifier = ">=2.1.0,<3.0.0" }, { name = "pygithub", specifier = ">=2.3.0,<3.0.0" }, { name = "pyyaml", specifier = ">=5.3.1,<7.0.0" }, From cbd64b09a32681d3b0ea097608bc62eb0d1587e0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 23 Mar 2026 12:37:17 +0000 Subject: [PATCH 02/15] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 6278bcc959..e832bdbe5b 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,10 @@ hide: ## Latest Changes +### Upgrades + +* ⬆️ Increase lower bound to `pydantic >=2.9.0.` and fix the test suite. PR [#15139](https://github.com/fastapi/fastapi/pull/15139) by [@svlandeg](https://github.com/svlandeg). + ### Docs * πŸ“ Fix duplicated words in docstrings. PR [#15116](https://github.com/fastapi/fastapi/pull/15116) by [@AhsanSheraz](https://github.com/AhsanSheraz). From 0227991a01e61bf5cdd93cc00e9e243f52b47a4a Mon Sep 17 00:00:00 2001 From: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com> Date: Mon, 23 Mar 2026 14:51:24 +0100 Subject: [PATCH 03/15] =?UTF-8?q?=F0=9F=94=A8=20Exclude=20spam=20comments?= =?UTF-8?q?=20from=20statistics=20in=20`scripts/people.py`=20(#15088)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/people.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/scripts/people.py b/scripts/people.py index 2e84fcc455..5718d65da9 100644 --- a/scripts/people.py +++ b/scripts/people.py @@ -7,12 +7,12 @@ from collections.abc import Container from datetime import datetime, timedelta, timezone from math import ceil from pathlib import Path -from typing import Any +from typing import Annotated, Any import httpx import yaml from github import Github -from pydantic import BaseModel, SecretStr +from pydantic import BaseModel, BeforeValidator, SecretStr from pydantic_settings import BaseSettings github_graphql_url = "https://api.github.com/graphql" @@ -21,6 +21,8 @@ questions_category_id = "DIC_kwDOCZduT84B6E2a" POINTS_PER_MINUTE_LIMIT = 84 # 5000 points per hour +MINIMIZED_COMMENTS_REASONS_TO_EXCLUDE = {"abuse", "off-topic", "duplicate", "spam"} + class RateLimiter: def __init__(self) -> None: @@ -102,8 +104,10 @@ query Q($after: String, $category_id: ID) { avatarUrl url } + minimizedReason } } + minimizedReason } } } @@ -118,6 +122,10 @@ query Q($after: String, $category_id: ID) { } """ +LowerStr = Annotated[ + str, BeforeValidator(lambda v: v.lower() if isinstance(v, str) else v) +] + class Author(BaseModel): login: str @@ -128,6 +136,7 @@ class Author(BaseModel): class CommentsNode(BaseModel): createdAt: datetime author: Author | None = None + minimizedReason: LowerStr | None = None class Replies(BaseModel): @@ -136,6 +145,7 @@ class Replies(BaseModel): class DiscussionsCommentsNode(CommentsNode): + minimizedReason: LowerStr | None = None replies: Replies @@ -278,7 +288,10 @@ def get_discussions_experts( discussion_author_name = discussion.author.login discussion_commentors: dict[str, datetime] = {} for comment in discussion.comments.nodes: - if comment.author: + if ( + comment.minimizedReason not in MINIMIZED_COMMENTS_REASONS_TO_EXCLUDE + and comment.author + ): authors[comment.author.login] = comment.author if comment.author.login != discussion_author_name: author_time = discussion_commentors.get( @@ -288,7 +301,10 @@ def get_discussions_experts( author_time, comment.createdAt ) for reply in comment.replies.nodes: - if reply.author: + if ( + reply.minimizedReason not in MINIMIZED_COMMENTS_REASONS_TO_EXCLUDE + and reply.author + ): authors[reply.author.login] = reply.author if reply.author.login != discussion_author_name: author_time = discussion_commentors.get( From fce9460f865928eb7d0393d8809bbc472e0c21cd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 23 Mar 2026 13:51:55 +0000 Subject: [PATCH 04/15] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index e832bdbe5b..53ca17db82 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -48,6 +48,7 @@ hide: ### Internal +* πŸ”¨ Exclude spam comments from statistics in `scripts/people.py`. PR [#15088](https://github.com/fastapi/fastapi/pull/15088) by [@YuriiMotov](https://github.com/YuriiMotov). * ⬆ Bump authlib from 1.6.7 to 1.6.9. PR [#15128](https://github.com/fastapi/fastapi/pull/15128) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump pyasn1 from 0.6.2 to 0.6.3. PR [#15143](https://github.com/fastapi/fastapi/pull/15143) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump ujson from 5.11.0 to 5.12.0. PR [#15150](https://github.com/fastapi/fastapi/pull/15150) by [@dependabot[bot]](https://github.com/apps/dependabot). From fd9e192cf4fae399c0d51dd23e2a137052eb6087 Mon Sep 17 00:00:00 2001 From: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com> Date: Mon, 23 Mar 2026 14:56:46 +0100 Subject: [PATCH 05/15] =?UTF-8?q?=F0=9F=92=84=20Fix=20code=20blocks=20in?= =?UTF-8?q?=20reference=20docs=20overflowing=20table=20width=20(#15094)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/css/custom.css | 6 ++++++ docs/en/mkdocs.yml | 1 + 2 files changed, 7 insertions(+) diff --git a/docs/en/docs/css/custom.css b/docs/en/docs/css/custom.css index e207197c75..bbfd49b55e 100644 --- a/docs/en/docs/css/custom.css +++ b/docs/en/docs/css/custom.css @@ -254,6 +254,12 @@ Inspired by Termynal's CSS tricks with modifications box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930; } +.doc-param-details .highlight { + overflow-x: auto; + width: 0; + min-width: 100%; +} + .md-typeset dfn { border-bottom: .05rem dotted var(--md-default-fg-color--light); cursor: help; diff --git a/docs/en/mkdocs.yml b/docs/en/mkdocs.yml index 0db3e7a95b..4614194981 100644 --- a/docs/en/mkdocs.yml +++ b/docs/en/mkdocs.yml @@ -279,6 +279,7 @@ markdown_extensions: pymdownx.caret: null pymdownx.highlight: line_spans: __span + linenums_style: pymdownx-inline pymdownx.inlinehilite: null pymdownx.keys: null pymdownx.mark: null From d0a6f208c5cb5daaa1de5ea5187729e3789d1dce Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 23 Mar 2026 13:57:14 +0000 Subject: [PATCH 06/15] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 53ca17db82..bb3c0f117e 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### Docs +* πŸ’„ Fix code blocks in reference docs overflowing table width. PR [#15094](https://github.com/fastapi/fastapi/pull/15094) by [@YuriiMotov](https://github.com/YuriiMotov). * πŸ“ Fix duplicated words in docstrings. PR [#15116](https://github.com/fastapi/fastapi/pull/15116) by [@AhsanSheraz](https://github.com/AhsanSheraz). * πŸ“ Add docs for `pyproject.toml` with `entrypoint`. PR [#15075](https://github.com/fastapi/fastapi/pull/15075) by [@tiangolo](https://github.com/tiangolo). * πŸ“ Update links in docs to no longer use the classes external-link and internal-link. PR [#15061](https://github.com/fastapi/fastapi/pull/15061) by [@tiangolo](https://github.com/tiangolo). From ea6e287eb398afe6a82c3ef71780e8451813f674 Mon Sep 17 00:00:00 2001 From: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com> Date: Mon, 23 Mar 2026 14:59:26 +0100 Subject: [PATCH 07/15] =?UTF-8?q?=F0=9F=93=9D=20Update=20docs=20for=20cont?= =?UTF-8?q?ributors=20and=20team=20members=20regarding=20translation=20PRs?= =?UTF-8?q?=20(#15200)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/contributing.md | 8 +++++++- docs/en/docs/management-tasks.md | 9 ++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/docs/en/docs/contributing.md b/docs/en/docs/contributing.md index 07031a235a..fe7318f6cd 100644 --- a/docs/en/docs/contributing.md +++ b/docs/en/docs/contributing.md @@ -191,7 +191,11 @@ If you see mistakes in your language, you can make suggestions to the prompt in #### Reviewing Translation PRs -You can also check the currently [existing pull requests](https://github.com/fastapi/fastapi/pulls) for your language. You can filter the pull requests by the ones with the label for your language. For example, for Spanish, the label is [`lang-es`](https://github.com/fastapi/fastapi/pulls?q=is%3Aopen+sort%3Aupdated-desc+label%3Alang-es+label%3Aawaiting-review). +We don’t require approval from native speakers for translation PRs generated automatically by our translation workflow. However, you can still review them and suggest improvements to the LLM prompt for that language to make the future translations better. + +You can check the currently [existing pull requests](https://github.com/fastapi/fastapi/pulls) for your language. You can filter the pull requests by the ones with the label for your language. For example, for Spanish, the label is [`lang-es`](https://github.com/fastapi/fastapi/pulls?q=is%3Aopen+sort%3Aupdated-desc+label%3Alang-es+label%3Aawaiting-review). + +You can also review already merged translation PRs. To do this, go to the [closed pull requests](https://github.com/fastapi/fastapi/pulls?q=is%3Apr+is%3Aclosed) and filter by your language label. For example, for Spanish, you can use [`lang-es`](https://github.com/fastapi/fastapi/pulls?q=is%3Apr+is%3Aclosed+label%3Alang-es). When reviewing a pull request, it's better not to suggest changes in the same pull request, because it is LLM generated, and it won't be possible to make sure that small individual changes are replicated in other similar sections, or that they are preserved when translating the same content again. @@ -203,6 +207,8 @@ Check the docs about [adding a pull request review](https://help.github.com/en/g /// +PRs with suggestions to the language-specific LLM prompt require approval from at least one native speaker. Your help here is very much appreciated! + #### Subscribe to Notifications for Your Language Check if there's a [GitHub Discussion](https://github.com/fastapi/fastapi/discussions/categories/translations) to coordinate translations for your language. You can subscribe to it, and when there's a new pull request to review, an automatic comment will be added to the discussion. diff --git a/docs/en/docs/management-tasks.md b/docs/en/docs/management-tasks.md index e4094c4a18..3388013a00 100644 --- a/docs/en/docs/management-tasks.md +++ b/docs/en/docs/management-tasks.md @@ -114,7 +114,14 @@ For these language translation PRs, confirm that: * The PR was automated (authored by @tiangolo), not made by another user. * It has the labels `lang-all` and `lang-{lang code}`. -* If the PR is approved by at least one native speaker, you can merge it. + +For PRs that update language-specific LLM prompts, confirm that: + +* The PR has the labels `lang-all` and `lang-{lang code}`. +* It is approved by at least one native speaker. +* In some cases you might need to translate several pages with new prompt to make sure it works as expected. + +If the PR meets the above conditions, you can merge it. 😎 ## Review PRs From 68ac0ab91e9b14c418013790fc0e420a827686b5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 23 Mar 2026 13:59:57 +0000 Subject: [PATCH 08/15] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index bb3c0f117e..3111ff735d 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### Docs +* πŸ“ Update docs for contributors and team members regarding translation PRs. PR [#15200](https://github.com/fastapi/fastapi/pull/15200) by [@YuriiMotov](https://github.com/YuriiMotov). * πŸ’„ Fix code blocks in reference docs overflowing table width. PR [#15094](https://github.com/fastapi/fastapi/pull/15094) by [@YuriiMotov](https://github.com/YuriiMotov). * πŸ“ Fix duplicated words in docstrings. PR [#15116](https://github.com/fastapi/fastapi/pull/15116) by [@AhsanSheraz](https://github.com/AhsanSheraz). * πŸ“ Add docs for `pyproject.toml` with `entrypoint`. PR [#15075](https://github.com/fastapi/fastapi/pull/15075) by [@tiangolo](https://github.com/tiangolo). From 122b6d490f844b6f716855d55a3e11237b7fb61f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Mon, 23 Mar 2026 15:08:07 +0100 Subject: [PATCH 09/15] =?UTF-8?q?=F0=9F=93=9D=20Add=20missing=20last=20rel?= =?UTF-8?q?ease=20notes=20dates=20(#15202)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 3111ff735d..1ef2fc29c7 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -73,7 +73,7 @@ hide: * ⬆ Bump actions/download-artifact from 7 to 8. PR [#15020](https://github.com/fastapi/fastapi/pull/15020) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump actions/upload-artifact from 6 to 7. PR [#15019](https://github.com/fastapi/fastapi/pull/15019) by [@dependabot[bot]](https://github.com/apps/dependabot). -## 0.135.1 +## 0.135.1 (2026-03-01) ### Fixes @@ -90,14 +90,14 @@ hide: * πŸ‘₯ Update FastAPI People - Contributors and Translators. PR [#15029](https://github.com/fastapi/fastapi/pull/15029) by [@tiangolo](https://github.com/tiangolo). * πŸ‘₯ Update FastAPI GitHub topic repositories. PR [#15036](https://github.com/fastapi/fastapi/pull/15036) by [@tiangolo](https://github.com/tiangolo). -## 0.135.0 +## 0.135.0 (2026-03-01) ### Features * ✨ Add support for Server Sent Events. PR [#15030](https://github.com/fastapi/fastapi/pull/15030) by [@tiangolo](https://github.com/tiangolo). * New docs: [Server-Sent Events (SSE)](https://fastapi.tiangolo.com/tutorial/server-sent-events/). -## 0.134.0 +## 0.134.0 (2026-02-27) ### Features @@ -117,7 +117,7 @@ hide: * πŸ”¨ Run tests with `pytest-xdist` and `pytest-cov`. PR [#14992](https://github.com/fastapi/fastapi/pull/14992) by [@YuriiMotov](https://github.com/YuriiMotov). -## 0.133.1 +## 0.133.1 (2026-02-25) ### Features From ab125daa4034435777853a2c5a6c47451414f9aa Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 23 Mar 2026 14:08:35 +0000 Subject: [PATCH 10/15] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 1ef2fc29c7..84d3765479 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### Docs +* πŸ“ Add missing last release notes dates. PR [#15202](https://github.com/fastapi/fastapi/pull/15202) by [@tiangolo](https://github.com/tiangolo). * πŸ“ Update docs for contributors and team members regarding translation PRs. PR [#15200](https://github.com/fastapi/fastapi/pull/15200) by [@YuriiMotov](https://github.com/YuriiMotov). * πŸ’„ Fix code blocks in reference docs overflowing table width. PR [#15094](https://github.com/fastapi/fastapi/pull/15094) by [@YuriiMotov](https://github.com/YuriiMotov). * πŸ“ Fix duplicated words in docstrings. PR [#15116](https://github.com/fastapi/fastapi/pull/15116) by [@AhsanSheraz](https://github.com/AhsanSheraz). From 25a3697cedc6e7dfb84e93c8ff965801486f00f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Mon, 23 Mar 2026 15:10:41 +0100 Subject: [PATCH 11/15] =?UTF-8?q?=F0=9F=94=96=20Release=20version=200.135.?= =?UTF-8?q?2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 2 ++ fastapi/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 84d3765479..387973e56f 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,8 @@ hide: ## Latest Changes +## 0.135.2 (2026-03-01) + ### Upgrades * ⬆️ Increase lower bound to `pydantic >=2.9.0.` and fix the test suite. PR [#15139](https://github.com/fastapi/fastapi/pull/15139) by [@svlandeg](https://github.com/svlandeg). diff --git a/fastapi/__init__.py b/fastapi/__init__.py index 06dacbd9dc..5ab8b2c955 100644 --- a/fastapi/__init__.py +++ b/fastapi/__init__.py @@ -1,6 +1,6 @@ """FastAPI framework, high performance, easy to learn, fast to code, ready for production""" -__version__ = "0.135.1" +__version__ = "0.135.2" from starlette import status as status From fa3588c38c7473aca7536b12d686102de4b0f407 Mon Sep 17 00:00:00 2001 From: Kadir Can Ozden <101993364+bysiber@users.noreply.github.com> Date: Tue, 24 Mar 2026 19:32:10 +0300 Subject: [PATCH 12/15] =?UTF-8?q?=E2=9C=8F=EF=B8=8F=20Fix=20typo=20for=20`?= =?UTF-8?q?client=5Fsecret`=20in=20OAuth2=20form=20docstrings=20(#14946)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fastapi/security/oauth2.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fastapi/security/oauth2.py b/fastapi/security/oauth2.py index 42674b476c..3fd9e41eb3 100644 --- a/fastapi/security/oauth2.py +++ b/fastapi/security/oauth2.py @@ -143,7 +143,7 @@ class OAuth2PasswordRequestForm: Form(json_schema_extra={"format": "password"}), Doc( """ - If there's a `client_password` (and a `client_id`), they can be sent + If there's a `client_secret` (and a `client_id`), they can be sent as part of the form fields. But the OAuth2 specification recommends sending the `client_id` and `client_secret` (if any) using HTTP Basic auth. @@ -309,7 +309,7 @@ class OAuth2PasswordRequestFormStrict(OAuth2PasswordRequestForm): Form(), Doc( """ - If there's a `client_password` (and a `client_id`), they can be sent + If there's a `client_secret` (and a `client_id`), they can be sent as part of the form fields. But the OAuth2 specification recommends sending the `client_id` and `client_secret` (if any) using HTTP Basic auth. From e2a0fd4ad851e45487f3f058a752107fe90bcad8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 24 Mar 2026 16:32:36 +0000 Subject: [PATCH 13/15] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 387973e56f..3a363c6593 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,10 @@ hide: ## Latest Changes +### Docs + +* ✏️ Fix typo for `client_secret` in OAuth2 form docstrings. PR [#14946](https://github.com/fastapi/fastapi/pull/14946) by [@bysiber](https://github.com/bysiber). + ## 0.135.2 (2026-03-01) ### Upgrades From 8238446b1beafb153b5fc0fef43341fe90690646 Mon Sep 17 00:00:00 2001 From: Sofie Van Landeghem Date: Tue, 24 Mar 2026 17:39:32 +0100 Subject: [PATCH 14/15] =?UTF-8?q?=F0=9F=91=B7=20Add=20ty=20check=20to=20`l?= =?UTF-8?q?int.sh`=20(#15136)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/lint.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/lint.sh b/scripts/lint.sh index 18cf52a848..a4d3422d3a 100755 --- a/scripts/lint.sh +++ b/scripts/lint.sh @@ -4,5 +4,6 @@ set -e set -x mypy fastapi +ty check fastapi ruff check fastapi tests docs_src scripts ruff format fastapi tests --check From 937d3075f9456dfcdfe2e1f6bc3b8b7b9a6c6cad Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 24 Mar 2026 16:39:58 +0000 Subject: [PATCH 15/15] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 3a363c6593..ebc1c79e2d 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -11,6 +11,10 @@ hide: * ✏️ Fix typo for `client_secret` in OAuth2 form docstrings. PR [#14946](https://github.com/fastapi/fastapi/pull/14946) by [@bysiber](https://github.com/bysiber). +### Internal + +* πŸ‘· Add ty check to `lint.sh`. PR [#15136](https://github.com/fastapi/fastapi/pull/15136) by [@svlandeg](https://github.com/svlandeg). + ## 0.135.2 (2026-03-01) ### Upgrades