From df6530e0020f0b26951fff58b02d0a7e9ab834d3 Mon Sep 17 00:00:00 2001 From: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com> Date: Sun, 1 Feb 2026 12:44:39 +0300 Subject: [PATCH 01/56] =?UTF-8?q?=F0=9F=8C=90=20Update=20translations=20fo?= =?UTF-8?q?r=20uk=20(update=20outdated,=20found=20by=20fixer=20tool)=20(#1?= =?UTF-8?q?4739)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/uk/docs/alternatives.md | 80 ++++++++++---------- docs/uk/docs/fastapi-cli.md | 108 +++++++++++++-------------- docs/uk/docs/features.md | 138 +++++++++++++++++++---------------- 3 files changed, 166 insertions(+), 160 deletions(-) diff --git a/docs/uk/docs/alternatives.md b/docs/uk/docs/alternatives.md index 786df45c5..d44ca794f 100644 --- a/docs/uk/docs/alternatives.md +++ b/docs/uk/docs/alternatives.md @@ -1,8 +1,8 @@ -# Альтернативи, натхнення та порівняння +# Альтернативи, натхнення та порівняння { #alternatives-inspiration-and-comparisons } -Що надихнуло на створення **FastAPI**, який він у порінянні з іншими альтернативами та чого він у них навчився. +Що надихнуло **FastAPI**, як він порівнюється з альтернативами та чого він у них навчився. -## Вступ +## Вступ { #intro } **FastAPI** не існувало б, якби не попередні роботи інших. @@ -12,17 +12,17 @@ Але в якийсь момент не було іншого виходу, окрім створення чогось, що надавало б усі ці функції, взявши найкращі ідеї з попередніх інструментів і поєднавши їх найкращим чином, використовуючи мовні функції, які навіть не були доступні раніше (Python 3.6+ підказки типів). -## Попередні інструменти +## Попередні інструменти { #previous-tools } -### Django +### Django { #django } Це найпопулярніший фреймворк Python, який користується широкою довірою. Він використовується для створення таких систем, як Instagram. Він відносно тісно пов’язаний з реляційними базами даних (наприклад, MySQL або PostgreSQL), тому мати базу даних NoSQL (наприклад, Couchbase, MongoDB, Cassandra тощо) як основний механізм зберігання не дуже просто. -Він був створений для створення HTML у серверній частині, а не для створення API, які використовуються сучасним інтерфейсом (як-от React, Vue.js і Angular) або іншими системами (як-от IoT пристрої), які спілкуються з ним. +Він був створений для створення HTML у серверній частині, а не для створення API, які використовуються сучасним інтерфейсом (як-от React, Vue.js і Angular) або іншими системами (як-от IoT пристрої), які спілкуються з ним. -### Django REST Framework +### Django REST Framework { #django-rest-framework } Фреймворк Django REST був створений як гнучкий інструментарій для створення веб-інтерфейсів API використовуючи Django в основі, щоб покращити його можливості API. @@ -42,7 +42,7 @@ Django REST Framework створив Том Крісті. Той самий тв /// -### Flask +### Flask { #flask } Flask — це «мікрофреймворк», він не включає інтеграцію бази даних, а також багато речей, які за замовчуванням є в Django. @@ -64,7 +64,7 @@ Flask — це «мікрофреймворк», він не включає ін /// -### Requests +### Requests { #requests } **FastAPI** насправді не є альтернативою **Requests**. Сфера їх застосування дуже різна. @@ -88,12 +88,12 @@ Requests мають дуже простий та інтуїтивно зрозу response = requests.get("http://example.com/some/url") ``` -Відповідна операція *роуту* API FastAPI може виглядати так: +Відповідна операція шляху API FastAPI може виглядати так: ```Python hl_lines="1" @app.get("/some/url") def read_url(): - return {"message": "Hello World"} + return {"message": "Hello World"} ``` Зверніть увагу на схожість у `requests.get(...)` і `@app.get(...)`. @@ -101,12 +101,12 @@ def read_url(): /// check | Надихнуло **FastAPI** на * Майте простий та інтуїтивно зрозумілий API. - * Використовуйте імена (операції) методів HTTP безпосередньо, простим та інтуїтивно зрозумілим способом. - * Розумні параметри за замовчуванням, але потужні налаштування. +* Використовуйте імена (операції) методів HTTP безпосередньо, простим та інтуїтивно зрозумілим способом. +* Розумні параметри за замовчуванням, але потужні налаштування. /// -### Swagger / OpenAPI +### Swagger / OpenAPI { #swagger-openapi } Головною функцією, яку я хотів від Django REST Framework, була автоматична API документація. @@ -124,18 +124,18 @@ def read_url(): Інтегрувати інструменти інтерфейсу на основі стандартів: - * Інтерфейс Swagger - * ReDoc +* Інтерфейс Swagger +* ReDoc Ці два було обрано через те, що вони досить популярні та стабільні, але, виконавши швидкий пошук, ви можете знайти десятки додаткових альтернативних інтерфейсів для OpenAPI (які можна використовувати з **FastAPI**). /// -### Фреймворки REST для Flask +### Фреймворки REST для Flask { #flask-rest-frameworks } Існує кілька фреймворків Flask REST, але, витративши час і роботу на їх дослідження, я виявив, що багато з них припинено або залишено, з кількома постійними проблемами, які зробили їх непридатними. -### Marshmallow +### Marshmallow { #marshmallow } Однією з головних функцій, необхідних для систем API, є "серіалізація", яка бере дані з коду (Python) і перетворює їх на щось, що можна надіслати через мережу. Наприклад, перетворення об’єкта, що містить дані з бази даних, на об’єкт JSON. Перетворення об’єктів `datetime` на строки тощо. @@ -153,7 +153,7 @@ Marshmallow створено для забезпечення цих функці /// -### Webargs +### Webargs { #webargs } Іншою важливою функцією, необхідною для API, є аналіз даних із вхідних запитів. @@ -175,7 +175,7 @@ Webargs був створений тими ж розробниками Marshmall /// -### APISpec +### APISpec { #apispec } Marshmallow і Webargs забезпечують перевірку, аналіз і серіалізацію як плагіни. @@ -205,7 +205,7 @@ APISpec був створений тими ж розробниками Marshmall /// -### Flask-apispec +### Flask-apispec { #flask-apispec } Це плагін Flask, який об’єднує Webargs, Marshmallow і APISpec. @@ -237,13 +237,13 @@ Flask-apispec був створений тими ж розробниками Mar /// -### NestJS (та Angular) +### NestJS (та Angular) { #nestjs-and-angular } Це навіть не Python, NestJS — це фреймворк NodeJS JavaScript (TypeScript), натхненний Angular. Це досягає чогось подібного до того, що можна зробити з Flask-apispec. -Він має інтегровану систему впровадження залежностей, натхненну Angular two. Він потребує попередньої реєстрації «injectables» (як і всі інші системи впровадження залежностей, які я знаю), тому це збільшує багатослівність та повторення коду. +Він має інтегровану систему впровадження залежностей, натхненну Angular 2. Він потребує попередньої реєстрації «injectables» (як і всі інші системи впровадження залежностей, які я знаю), тому це збільшує багатослівність та повторення коду. Оскільки параметри описані за допомогою типів TypeScript (подібно до підказок типу Python), підтримка редактора досить хороша. @@ -259,7 +259,7 @@ Flask-apispec був створений тими ж розробниками Mar /// -### Sanic +### Sanic { #sanic } Це був один із перших надзвичайно швидких фреймворків Python на основі `asyncio`. Він був дуже схожий на Flask. @@ -279,7 +279,7 @@ Flask-apispec був створений тими ж розробниками Mar /// -### Falcon +### Falcon { #falcon } Falcon — ще один високопродуктивний фреймворк Python, він розроблений як мінімальний і працює як основа інших фреймворків, таких як Hug. @@ -297,7 +297,7 @@ Falcon — ще один високопродуктивний фреймворк /// -### Molten +### Molten { #molten } Я відкрив для себе Molten на перших етапах створення **FastAPI**. І він має досить схожі ідеї: @@ -321,7 +321,7 @@ Falcon — ще один високопродуктивний фреймворк /// -### Hug +### Hug { #hug } Hug був одним із перших фреймворків, який реалізував оголошення типів параметрів API за допомогою підказок типу Python. Це була чудова ідея, яка надихнула інші інструменти зробити те саме. @@ -351,7 +351,7 @@ Hug надихнув частину APIStar і був одним із найбі /// -### APIStar (<= 0,5) +### APIStar (<= 0,5) { #apistar-0-5 } Безпосередньо перед тим, як вирішити створити **FastAPI**, я знайшов сервер **APIStar**. Він мав майже все, що я шукав, і мав чудовий дизайн. @@ -379,9 +379,9 @@ Hug надихнув частину APIStar і був одним із найбі APIStar створив Том Крісті. Той самий хлопець, який створив: - * Django REST Framework - * Starlette (на якому базується **FastAPI**) - * Uvicorn (використовується Starlette і **FastAPI**) +* Django REST Framework +* Starlette (на якому базується **FastAPI**) +* Uvicorn (використовується Starlette і **FastAPI**) /// @@ -393,13 +393,15 @@ APIStar створив Том Крісті. Той самий хлопець, я І після тривалого пошуку подібної структури та тестування багатьох різних альтернатив, APIStar став найкращим доступним варіантом. - Потім APIStar перестав існувати як сервер, і було створено Starlette, який став новою кращою основою для такої системи. Це стало останнім джерелом натхнення для створення **FastAPI**. Я вважаю **FastAPI** «духовним спадкоємцем» APIStar, удосконалюючи та розширюючи функції, систему введення тексту та інші частини на основі досвіду, отриманого від усіх цих попередніх інструментів. + Потім APIStar перестав існувати як сервер, і було створено Starlette, який став новою кращою основою для такої системи. Це стало останнім джерелом натхнення для створення **FastAPI**. + + Я вважаю **FastAPI** «духовним спадкоємцем» APIStar, удосконалюючи та розширюючи функції, систему типізації та інші частини на основі досвіду, отриманого від усіх цих попередніх інструментів. /// -## Використовується **FastAPI** +## Використовується **FastAPI** { #used-by-fastapi } -### Pydantic +### Pydantic { #pydantic } Pydantic — це бібліотека для визначення перевірки даних, серіалізації та документації (за допомогою схеми JSON) на основі підказок типу Python. @@ -415,9 +417,9 @@ Pydantic — це бібліотека для визначення переві /// -### Starlette +### Starlette { #starlette } -Starlette — це легкий фреймворк/набір інструментів ASGI, який ідеально підходить для створення високопродуктивних asyncio сервісів. +Starlette — це легкий фреймворк/набір інструментів ASGI, який ідеально підходить для створення високопродуктивних asyncio сервісів. Він дуже простий та інтуїтивно зрозумілий. Його розроблено таким чином, щоб його можна було легко розширювати та мати модульні компоненти. @@ -460,7 +462,7 @@ ASGI — це новий «стандарт», який розробляєтьс /// -### Uvicorn +### Uvicorn { #uvicorn } Uvicorn — це блискавичний сервер ASGI, побудований на uvloop і httptools. @@ -472,12 +474,12 @@ Uvicorn — це блискавичний сервер ASGI, побудован Основний веб-сервер для запуску програм **FastAPI**. - Ви можете поєднати його з Gunicorn, щоб мати асинхронний багатопроцесний сервер. + Ви також можете використати параметр командного рядка `--workers`, щоб мати асинхронний багатопроцесний сервер. Додаткову інформацію див. у розділі [Розгортання](deployment/index.md){.internal-link target=_blank}. /// -## Орієнтири та швидкість +## Орієнтири та швидкість { #benchmarks-and-speed } Щоб зрозуміти, порівняти та побачити різницю між Uvicorn, Starlette і FastAPI, перегляньте розділ про [Бенчмарки](benchmarks.md){.internal-link target=_blank}. diff --git a/docs/uk/docs/fastapi-cli.md b/docs/uk/docs/fastapi-cli.md index f18b10471..eb5538230 100644 --- a/docs/uk/docs/fastapi-cli.md +++ b/docs/uk/docs/fastapi-cli.md @@ -1,83 +1,75 @@ -# FastAPI CLI +# FastAPI CLI { #fastapi-cli } -**FastAPI CLI** це програма командного рядка, яку Ви можете використовувати, щоб обслуговувати Ваш додаток FastAPI, керувати Вашими FastApi проектами, тощо. +**FastAPI CLI** — це програма командного рядка, яку ви можете використовувати, щоб обслуговувати ваш застосунок FastAPI, керувати вашим проєктом FastAPI тощо. -Коли Ви встановлюєте FastApi (тобто виконуєте `pip install "fastapi[standard]"`), Ви також встановлюєте пакунок `fastapi-cli`, цей пакунок надає команду `fastapi` в терміналі. +Коли ви встановлюєте FastAPI (наприклад, за допомогою `pip install "fastapi[standard]"`), він включає пакет під назвою `fastapi-cli`, цей пакет надає команду `fastapi` у терміналі. -Для запуску Вашого FastAPI проекту для розробки, Ви можете скористатись командою `fastapi dev`: +Щоб запустити ваш застосунок FastAPI для розробки, ви можете використати команду `fastapi dev`:
```console -$ fastapi dev main.py -INFO Using path main.py -INFO Resolved absolute path /home/user/code/awesomeapp/main.py -INFO Searching for package file structure from directories with __init__.py files -INFO Importing from /home/user/code/awesomeapp - - ╭─ Python module file ─╮ - │ │ - │ 🐍 main.py │ - │ │ - ╰──────────────────────╯ - -INFO Importing module main -INFO Found importable FastAPI app - - ╭─ Importable FastAPI app ─╮ - │ │ - │ from main import app │ - │ │ - ╰──────────────────────────╯ - -INFO Using import string main:app - - ╭────────── FastAPI CLI - Development mode ───────────╮ - │ │ - │ Serving at: http://127.0.0.1:8000 │ - │ │ - │ API docs: http://127.0.0.1:8000/docs │ - │ │ - │ Running in development mode, for production use: │ - │ │ - fastapi run - │ │ - ╰─────────────────────────────────────────────────────╯ - -INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp'] -INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) -INFO: Started reloader process [2265862] using WatchFiles -INFO: Started server process [2265873] -INFO: Waiting for application startup. -INFO: Application startup complete. +$ fastapi dev main.py + + FastAPI Starting development server 🚀 + + Searching for package file structure from directories with + __init__.py files + Importing from /home/user/code/awesomeapp + + module 🐍 main.py + + code Importing the FastAPI app object from the module with the + following code: + + from main import app + + app Using import string: main:app + + server Server started at http://127.0.0.1:8000 + server Documentation at http://127.0.0.1:8000/docs + + tip Running in development mode, for production use: + fastapi run + + Logs: + + INFO Will watch for changes in these directories: + ['/home/user/code/awesomeapp'] + INFO Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to + quit) + INFO Started reloader process [383138] using WatchFiles + INFO Started server process [383153] + INFO Waiting for application startup. + INFO Application startup complete. ```
-Програма командного рядка `fastapi` це **FastAPI CLI**. +Програма командного рядка під назвою `fastapi` — це **FastAPI CLI**. -FastAPI CLI приймає шлях до Вашої Python програми (напр. `main.py`) і автоматично виявляє екземпляр `FastAPI` (зазвичай названий `app`), обирає коректний процес імпорту, а потім обслуговує його. +FastAPI CLI бере шлях до вашої Python-програми (наприклад, `main.py`) і автоматично виявляє екземпляр `FastAPI` (зазвичай з назвою `app`), визначає правильний процес імпорту, а потім обслуговує його. -Натомість, для запуску у продакшн використовуйте `fastapi run`. 🚀 +Натомість, для продакшн ви використали б `fastapi run`. 🚀 -Всередині **FastAPI CLI** використовує Uvicorn, високопродуктивний, production-ready, ASGI cервер. 😎 +Внутрішньо **FastAPI CLI** використовує Uvicorn, високопродуктивний, production-ready, ASGI сервер. 😎 -## `fastapi dev` +## `fastapi dev` { #fastapi-dev } -Використання `fastapi dev` ініціює режим розробки. +Запуск `fastapi dev` ініціює режим розробки. -За замовчуванням, **автоматичне перезавантаження** увімкнене, автоматично перезавантажуючи сервер кожного разу, коли Ви змінюєте Ваш код. Це ресурсо-затратно, та може бути менш стабільним, ніж коли воно вимкнене. Ви повинні використовувати його тільки під час розробки. Воно також слухає IP-адресу `127.0.0.1`, що є IP Вашого девайсу для самостійної комунікації з самим собою (`localhost`). +За замовчуванням **auto-reload** увімкнено, і сервер автоматично перезавантажується, коли ви вносите зміни у ваш код. Це ресурсоємно та може бути менш стабільним, ніж коли його вимкнено. Вам слід використовувати це лише для розробки. Також він слухає IP-адресу `127.0.0.1`, яка є IP-адресою для того, щоб ваша машина могла взаємодіяти лише сама з собою (`localhost`). -## `fastapi run` +## `fastapi run` { #fastapi-run } -Виконання `fastapi run` запустить FastAPI у продакшн-режимі за замовчуванням. +Виконання `fastapi run` за замовчуванням запускає FastAPI у продакшн-режимі. -За замовчуванням, **автоматичне перезавантаження** вимкнене. Воно також прослуховує IP-адресу `0.0.0.0`, що означає всі доступні IP адреси, тим самим даючи змогу будь-кому комунікувати з девайсом. Так Ви зазвичай будете запускати його у продакшн, наприклад у контейнері. +За замовчуванням **auto-reload** вимкнено. Також він слухає IP-адресу `0.0.0.0`, що означає всі доступні IP-адреси, таким чином він буде публічно доступним для будь-кого, хто може взаємодіяти з машиною. Зазвичай саме так ви запускатимете його в продакшн, наприклад у контейнері. -В більшості випадків Ви можете (і маєте) мати "termination proxy", який обробляє HTTPS для Вас, це залежить від способу розгортання вашого додатку, Ваш провайдер може зробити це для Вас, або Вам потрібно налаштувати його самостійно. +У більшості випадків ви (і вам слід) матимете «termination proxy», який обробляє HTTPS для вас зверху; це залежатиме від того, як ви розгортаєте ваш застосунок: ваш провайдер може зробити це за вас, або вам може знадобитися налаштувати це самостійно. -/// tip +/// tip | Порада -Ви можете дізнатись більше про це у [документації про розгортування](deployment/index.md){.internal-link target=_blank}. +Ви можете дізнатися більше про це в [документації з розгортання](deployment/index.md){.internal-link target=_blank}. /// diff --git a/docs/uk/docs/features.md b/docs/uk/docs/features.md index aa0ef7c79..d8233115f 100644 --- a/docs/uk/docs/features.md +++ b/docs/uk/docs/features.md @@ -1,21 +1,21 @@ -# Функціональні можливості +# Функціональні можливості { #features } -## Функціональні можливості FastAPI +## Функціональні можливості FastAPI { #fastapi-features } **FastAPI** надає вам такі можливості: -### Використання відкритих стандартів +### На основі відкритих стандартів { #based-on-open-standards } * OpenAPI для створення API, включаючи оголошення шляхів, операцій, параметрів, тіл запитів, безпеки тощо. * Автоматична документація моделей даних за допомогою JSON Schema (оскільки OpenAPI базується саме на JSON Schema). * Розроблено на основі цих стандартів після ретельного аналізу, а не як додатковий рівень поверх основної архітектури. -* Це також дає змогу автоматично **генерувати код клієнта** багатьма мовами. +* Це також дає змогу використовувати автоматичну **генерацію клієнтського коду** багатьма мовами. -### Автоматична генерація документації +### Автоматична документація { #automatic-docs } -Інтерактивна документація API та вебінтерфейс для його дослідження. Оскільки фреймворк базується на OpenAPI, є кілька варіантів, два з яких включені за замовчуванням. +Інтерактивна документація API та вебінтерфейси для його дослідження. Оскільки фреймворк базується на OpenAPI, є кілька варіантів, 2 з яких включені за замовчуванням. -* Swagger UI — дозволяє інтерактивно переглядати API, викликати та тестувати його прямо у браузері. +* Swagger UI — з інтерактивним дослідженням, викликом і тестуванням вашого API прямо з браузера. ![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png) @@ -23,23 +23,25 @@ ![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png) -### Тільки сучасний Python +### Лише сучасний Python { #just-modern-python } -FastAPI використовує стандартні **типи Python** (завдяки Pydantic). Вам не потрібно вивчати новий синтаксис — лише стандартний сучасний Python. +Усе базується на стандартних оголошеннях **типів Python** (завдяки Pydantic). Жодного нового синтаксису для вивчення. Лише стандартний сучасний Python. -Якщо вам потрібне коротке нагадування про використання типів у Python (навіть якщо ви не використовуєте FastAPI), перегляньте короткий підручник: [Вступ до типів Python](python-types.md){.internal-link target=_blank}. +Якщо вам потрібно 2-хвилинне нагадування про те, як використовувати типи Python (навіть якщо ви не використовуєте FastAPI), перегляньте короткий підручник: [Типи Python](python-types.md){.internal-link target=_blank}. -Ось приклад стандартного Python-коду з типами: +Ви пишете стандартний Python з типами: ```Python from datetime import date + from pydantic import BaseModel -# Оголошення змінної як str -# з підтримкою автодоповнення у редакторі +# Оголосіть змінну як str +# та отримайте підтримку редактора всередині функції def main(user_id: str): return user_id + # Модель Pydantic class User(BaseModel): id: int @@ -47,7 +49,7 @@ class User(BaseModel): joined: date ``` -Приклад використання цієї моделі: +Далі це можна використовувати так: ```Python my_user: User = User(id=3, name="John Doe", joined="2018-07-19") @@ -65,19 +67,21 @@ my_second_user: User = User(**second_user_data) `**second_user_data` означає: -Передати ключі та значення словника `second_user_data` як аргументи у вигляді "ключ-значення", еквівалентно `User(id=4, name="Mary", joined="2018-11-30")`. +Передати ключі та значення словника `second_user_data` безпосередньо як аргументи у вигляді «ключ-значення», еквівалентно: `User(id=4, name="Mary", joined="2018-11-30")` /// -### Підтримка редакторів (IDE) +### Підтримка редакторів (IDE) { #editor-support } -Фреймворк спроєктований так, щоб бути легким і інтуїтивно зрозумілим. Усі рішення тестувалися у різних редакторах ще до початку розробки, щоб забезпечити найкращий досвід програмування. +Увесь фреймворк спроєктовано так, щоб ним було легко та інтуїтивно користуватися; усі рішення тестувалися у кількох редакторах ще до початку розробки, щоб забезпечити найкращий досвід розробки. -За результатами опитувань розробників Python однією з найпопулярніших функцій є "автодоповнення". +З опитувань розробників Python зрозуміло що однією з найуживаніших функцій є «автодоповнення». -**FastAPI** повністю підтримує автодоповнення у всіх місцях, тому вам рідко доведеться повертатися до документації. +Увесь фреймворк **FastAPI** побудований так, щоб це забезпечити. Автодоповнення працює всюди. -Приклад автодоповнення у редакторах: +Вам рідко доведеться повертатися до документації. + +Ось як ваш редактор може вам допомогти: * у Visual Studio Code: @@ -87,17 +91,25 @@ my_second_user: User = User(**second_user_data) ![editor support](https://fastapi.tiangolo.com/img/pycharm-completion.png) -### Короткий код -FastAPI має розумні налаштування **за замовчуванням**, але всі параметри можна налаштовувати відповідно до ваших потреб. Однак за замовчуванням все "просто працює". +Ви отримаєте автодоповнення в коді, який раніше могли вважати навіть неможливим. Наприклад, для ключа `price` всередині JSON body (який міг бути вкладеним), що надходить із запиту. + +Більше не доведеться вводити неправильні назви ключів, постійно повертатися до документації або прокручувати вгору-вниз, щоб знайти, чи ви зрештою використали `username` чи `user_name`. + +### Короткий код { #short } + +FastAPI має розумні **налаштування за замовчуванням** для всього, з можливістю конфігурації всюди. Усі параметри можна точно налаштувати під ваші потреби та визначити потрібний вам API. + +Але за замовчуванням усе **«просто працює»**. + +### Валідація { #validation } -### Валідація * Підтримка валідації для більшості (або всіх?) **типів даних Python**, зокрема: * JSON-об'єктів (`dict`). - * JSON-списків (`list`) з визначенням типів елементів. - * Рядків (`str`) із мінімальною та максимальною довжиною. - * Чисел (`int`, `float`) з обмеженнями мінімальних та максимальних значень тощо. + * JSON-масивів (`list`) із визначенням типів елементів. + * Полів-рядків (`str`) із визначенням мінімальної та максимальної довжини. + * Чисел (`int`, `float`) з мінімальними та максимальними значеннями тощо. -* Валідація складніших типів, таких як: +* Валідація для більш екзотичних типів, як-от: * URL. * Email. * UUID. @@ -105,55 +117,55 @@ FastAPI має розумні налаштування **за замовчува Уся валідація виконується через надійний та перевірений **Pydantic**. -### Безпека та автентифікація +### Безпека та автентифікація { #security-and-authentication } -**FastAPI** підтримує вбудовану автентифікацію та авторизацію, без прив’язки до конкретних баз даних чи моделей даних. +Інтегровані безпека та автентифікація. Без жодних компромісів із базами даних чи моделями даних. -Підтримуються всі схеми безпеки OpenAPI, включаючи: +Підтримуються всі схеми безпеки, визначені в OpenAPI, включно з: * HTTP Basic. -* **OAuth2** (також із підтримкою **JWT-токенів**). Див. підручник: [OAuth2 із JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank}. +* **OAuth2** (також із підтримкою **JWT tokens**). Перегляньте підручник: [OAuth2 із JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank}. * Ключі API в: * Заголовках. * Параметрах запиту. * Cookies тощо. -А також усі можливості безпеки від Starlette (зокрема **сесійні cookies**). +А також усі можливості безпеки від Starlette (зокрема **session cookies**). -Усі вони створені як багаторазові інструменти та компоненти, які легко інтегруються з вашими системами, сховищами даних, реляційними та NoSQL базами даних тощо. +Усе це зроблено як багаторазові інструменти та компоненти, які легко інтегруються з вашими системами, сховищами даних, реляційними та NoSQL базами даних тощо. -### Впровадження залежностей +### Впровадження залежностей { #dependency-injection } -**FastAPI** містить надзвичайно просту у використанні, але потужну систему впровадження залежностей. +FastAPI містить надзвичайно просту у використанні, але надзвичайно потужну систему Dependency Injection. -* Залежності можуть мати власні залежності, утворюючи ієрархію або **"граф залежностей"**. -* Усі залежності автоматично керуються фреймворком. -* Усі залежності можуть отримувати дані з запитів і розширювати **обмеження операції за шляхом** та автоматичну документацію. -* **Автоматична валідація** навіть для параметрів *операцій шляху*, визначених у залежностях. -* Підтримка складних систем автентифікації користувачів, **з'єднань із базами даних** тощо. -* **Жодних обмежень** щодо використання баз даних, фронтендів тощо, але водночас проста інтеграція з усіма ними. +* Навіть залежності можуть мати власні залежності, утворюючи ієрархію або **«граф» залежностей**. +* Усе **автоматично обробляється** фреймворком. +* Усі залежності можуть вимагати дані із запитів і **розширювати обмеження операції шляху** та автоматичну документацію. +* **Автоматична валідація** навіть для параметрів *операції шляху*, визначених у залежностях. +* Підтримка складних систем автентифікації користувачів, **підключень до баз даних** тощо. +* **Жодних компромісів** із базами даних, фронтендами тощо. Але проста інтеграція з усіма ними. -### Немає обмежень на "плагіни" +### Необмежені «плагіни» { #unlimited-plug-ins } -Або іншими словами, вони не потрібні – просто імпортуйте та використовуйте необхідний код. +Інакше кажучи, вони не потрібні — імпортуйте та використовуйте код, який вам потрібен. -Будь-яка інтеграція спроєктована настільки просто (з використанням залежностей), що ви можете створити "плагін" для свого застосунку всього у 2 рядках коду, використовуючи ту саму структуру та синтаксис, що й для ваших *операцій шляху*. +Будь-яка інтеграція спроєктована так, щоб її було дуже просто використовувати (із залежностями), тож ви можете створити «плагін» для свого застосунку у 2 рядках коду, використовуючи ту саму структуру та синтаксис, що й для ваших *операцій шляху*. -### Протестовано +### Протестовано { #tested } * 100% покриття тестами. * 100% анотована типами кодова база. -* Використовується у робочих середовищах. +* Використовується в production-застосунках. -## Можливості Starlette +## Можливості Starlette { #starlette-features } **FastAPI** повністю сумісний із (та побудований на основі) Starlette. Тому будь-який додатковий код Starlette, який ви маєте, також працюватиме. -**FastAPI** фактично є підкласом **Starlette**. Тому, якщо ви вже знайомі зі Starlette або використовуєте його, більшість функціональності працюватиме так само. +`FastAPI` фактично є підкласом `Starlette`. Тому, якщо ви вже знайомі зі Starlette або використовуєте його, більшість функціональності працюватиме так само. -З **FastAPI** ви отримуєте всі можливості **Starlette** (адже FastAPI — це, по суті, Starlette на стероїдах): +З **FastAPI** ви отримуєте всі можливості **Starlette** (адже FastAPI — це просто Starlette на стероїдах): -* Разюча продуктивність. Це один із найшвидших фреймворків на Python, на рівні з **NodeJS** і **Go**. +* Разюча продуктивність. Це один із найшвидших доступних Python-фреймворків, на рівні з **NodeJS** і **Go**. * Підтримка **WebSocket**. * Фонові задачі у процесі. * Події запуску та завершення роботи. @@ -163,27 +175,27 @@ FastAPI має розумні налаштування **за замовчува * 100% покриття тестами. * 100% анотована типами кодова база. -## Можливості Pydantic +## Можливості Pydantic { #pydantic-features } **FastAPI** повністю сумісний із (та побудований на основі) Pydantic. Тому будь-який додатковий код Pydantic, який ви маєте, також працюватиме. -Включаючи зовнішні бібліотеки, побудовані також на Pydantic, такі як ORM, ODM для баз даних. +Включно із зовнішніми бібліотеками, які також базуються на Pydantic, як-от ORM-и, ODM-и для баз даних. -Це також означає, що в багатьох випадках ви можете передати той самий об'єкт, який отримуєте з запиту, **безпосередньо в базу даних**, оскільки все автоматично перевіряється. +Це також означає, що в багатьох випадках ви можете передати той самий об'єкт, який отримуєте із запиту, **безпосередньо в базу даних**, оскільки все автоматично перевіряється. -Те ж саме відбувається й у зворотному напрямку — у багатьох випадках ви можете просто передати об'єкт, який отримуєте з бази даних, **безпосередньо клієнту**. +Те саме застосовується й у зворотному напрямку — у багатьох випадках ви можете просто передати об'єкт, який отримуєте з бази даних, **безпосередньо клієнту**. З **FastAPI** ви отримуєте всі можливості **Pydantic** (адже FastAPI базується на Pydantic для обробки всіх даних): -* **Ніякої плутанини** : - * Не потрібно вчити нову мову для визначення схем. +* **Ніякої плутанини**: + * Не потрібно вчити нову мікромову для визначення схем. * Якщо ви знаєте типи Python, ви знаєте, як використовувати Pydantic. -* Легко працює з вашим **IDE/лінтером/мозком**: - * Оскільки структури даних Pydantic є просто екземплярами класів, які ви визначаєте; автодоповнення, лінтинг, mypy і ваша інтуїція повинні добре працювати з вашими перевіреними даними. -* Валідація **складних структур**: - * Використання ієрархічних моделей Pydantic. Python `typing`, `List` і `Dict` тощо. - * Валідатори дозволяють чітко і просто визначати, перевіряти й документувати складні схеми даних у вигляді JSON-схеми. - * Ви можете мати глибоко **вкладені JSON об'єкти** та перевірити та анотувати їх всі. +* Легко працює з вашим **IDE/linter/мозком**: + * Оскільки структури даних pydantic є просто екземплярами класів, які ви визначаєте; автодоповнення, лінтинг, mypy і ваша інтуїція повинні добре працювати з вашими перевіреними даними. +* Валідує **складні структури**: + * Використання ієрархічних моделей Pydantic, Python `typing`’s `List` і `Dict` тощо. + * Валідатори дають змогу складні схеми даних чітко й просто визначати, перевіряти й документувати як JSON Schema. + * Ви можете мати глибоко **вкладені JSON** об'єкти, і всі вони будуть валідовані та анотовані. * **Розширюваність**: - * Pydantic дозволяє визначати користувацькі типи даних або розширювати валідацію методами в моделі декоратором `validator`. + * Pydantic дозволяє визначати користувацькі типи даних або ви можете розширити валідацію методами в моделі, позначеними декоратором validator. * 100% покриття тестами. From 07f08fc79a021cbc06d194f0a32f521253c6ed8c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 1 Feb 2026 09:44:59 +0000 Subject: [PATCH 02/56] =?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 eb72d559d..699b96696 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -19,6 +19,7 @@ hide: ### Translations +* 🌐 Update translations for uk (update outdated, found by fixer tool). PR [#14739](https://github.com/fastapi/fastapi/pull/14739) by [@YuriiMotov](https://github.com/YuriiMotov). * 🌐 Update translations for tr (update-outdated). PR [#14745](https://github.com/fastapi/fastapi/pull/14745) by [@tiangolo](https://github.com/tiangolo). * 🌐 Update `llm-prompt.md` for Korean language. PR [#14763](https://github.com/fastapi/fastapi/pull/14763) by [@seuthootDev](https://github.com/seuthootDev). * 🌐 Update translations for ko (update outdated, found by fixer tool). PR [#14738](https://github.com/fastapi/fastapi/pull/14738) by [@YuriiMotov](https://github.com/YuriiMotov). From 3626d764c13cb12414b2b1a254af075f2799c716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Mon, 2 Feb 2026 02:24:23 -0800 Subject: [PATCH 03/56] =?UTF-8?q?=F0=9F=91=A5=20Update=20FastAPI=20People?= =?UTF-8?q?=20-=20Contributors=20and=20Translators=20(#14796)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: github-actions[bot] --- docs/en/data/contributors.yml | 18 ++-- docs/en/data/translation_reviewers.yml | 114 ++++++++++++++----------- docs/en/data/translators.yml | 43 +++++----- 3 files changed, 95 insertions(+), 80 deletions(-) diff --git a/docs/en/data/contributors.yml b/docs/en/data/contributors.yml index 0c144cd4c..41115ccbd 100644 --- a/docs/en/data/contributors.yml +++ b/docs/en/data/contributors.yml @@ -1,17 +1,17 @@ tiangolo: login: tiangolo - count: 857 + count: 871 avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4 url: https://github.com/tiangolo dependabot: login: dependabot - count: 130 + count: 133 avatarUrl: https://avatars.githubusercontent.com/in/29110?v=4 url: https://github.com/apps/dependabot alejsdev: login: alejsdev count: 53 - avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=85ceac49fb87138aebe8d663912e359447329090&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=0facffe3abf87f57a1f05fa773d1119cc5c2f6a5&v=4 url: https://github.com/alejsdev pre-commit-ci: login: pre-commit-ci @@ -20,8 +20,8 @@ pre-commit-ci: url: https://github.com/apps/pre-commit-ci YuriiMotov: login: YuriiMotov - count: 36 - avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=b9b13d598dddfab529a52d264df80a900bfe7060&v=4 + count: 38 + avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=bc48be95c429989224786106b027f3c5e40cc354&v=4 url: https://github.com/YuriiMotov github-actions: login: github-actions @@ -40,7 +40,7 @@ dmontagu: url: https://github.com/dmontagu svlandeg: login: svlandeg - count: 16 + count: 17 avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4 url: https://github.com/svlandeg nilslindemann: @@ -126,7 +126,7 @@ hitrust: ShahriyarR: login: ShahriyarR count: 4 - avatarUrl: https://avatars.githubusercontent.com/u/3852029?u=631b2ae59360ab380c524b32bc3d245aff1165af&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/3852029?u=2dc6402d9053ee53f7afc407089cbab21c68f21d&v=4 url: https://github.com/ShahriyarR adriangb: login: adriangb @@ -266,7 +266,7 @@ Nimitha-jagadeesha: lucaromagnoli: login: lucaromagnoli count: 3 - avatarUrl: https://avatars.githubusercontent.com/u/38782977?u=15df02e806a2293af40ac619fba11dbe3c0c4fd4&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/38782977?u=a09a2e916625fa035f9dfa25ebc58e07aac8ec36&v=4 url: https://github.com/lucaromagnoli salmantec: login: salmantec @@ -521,7 +521,7 @@ s111d: estebanx64: login: estebanx64 count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/10840422?u=1900887aeed268699e5ea6f3fb7db614f7b77cd3&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/10840422?u=812422ae5d6a4bc5ff331c901fc54f9ab3cecf5c&v=4 url: https://github.com/estebanx64 ndimares: login: ndimares diff --git a/docs/en/data/translation_reviewers.yml b/docs/en/data/translation_reviewers.yml index 62db8e805..3d321818f 100644 --- a/docs/en/data/translation_reviewers.yml +++ b/docs/en/data/translation_reviewers.yml @@ -10,12 +10,12 @@ Xewus: url: https://github.com/Xewus sodaMelon: login: sodaMelon - count: 127 + count: 128 avatarUrl: https://avatars.githubusercontent.com/u/66295123?u=be939db90f1119efee9e6110cc05066ff1f40f00&v=4 url: https://github.com/sodaMelon ceb10n: login: ceb10n - count: 117 + count: 119 avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4 url: https://github.com/ceb10n tokusumi: @@ -25,7 +25,7 @@ tokusumi: url: https://github.com/tokusumi hard-coders: login: hard-coders - count: 96 + count: 102 avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=78d12d1acdf853c817700145e73de7fd9e5d068b&v=4 url: https://github.com/hard-coders hasansezertasan: @@ -50,7 +50,7 @@ AlertRED: url: https://github.com/AlertRED tiangolo: login: tiangolo - count: 73 + count: 78 avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4 url: https://github.com/tiangolo Alexandrhub: @@ -58,26 +58,31 @@ Alexandrhub: count: 68 avatarUrl: https://avatars.githubusercontent.com/u/119126536?u=9fc0d48f3307817bafecc5861eb2168401a6cb04&v=4 url: https://github.com/Alexandrhub +cassiobotaro: + login: cassiobotaro + count: 64 + avatarUrl: https://avatars.githubusercontent.com/u/3127847?u=a08022b191ddbd0a6159b2981d9d878b6d5bb71f&v=4 + url: https://github.com/cassiobotaro waynerv: login: waynerv count: 63 avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4 url: https://github.com/waynerv -cassiobotaro: - login: cassiobotaro - count: 62 - avatarUrl: https://avatars.githubusercontent.com/u/3127847?u=a08022b191ddbd0a6159b2981d9d878b6d5bb71f&v=4 - url: https://github.com/cassiobotaro +nilslindemann: + login: nilslindemann + count: 61 + avatarUrl: https://avatars.githubusercontent.com/u/6892179?u=1dca6a22195d6cd1ab20737c0e19a4c55d639472&v=4 + url: https://github.com/nilslindemann mattwang44: login: mattwang44 count: 61 avatarUrl: https://avatars.githubusercontent.com/u/24987826?u=58e37fb3927b9124b458945ac4c97aa0f1062d85&v=4 url: https://github.com/mattwang44 -nilslindemann: - login: nilslindemann - count: 59 - avatarUrl: https://avatars.githubusercontent.com/u/6892179?u=1dca6a22195d6cd1ab20737c0e19a4c55d639472&v=4 - url: https://github.com/nilslindemann +YuriiMotov: + login: YuriiMotov + count: 56 + avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=bc48be95c429989224786106b027f3c5e40cc354&v=4 + url: https://github.com/YuriiMotov Laineyzhang55: login: Laineyzhang55 count: 48 @@ -88,26 +93,21 @@ Kludex: count: 47 avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=df8a3f06ba8f55ae1967a3e2d5ed882903a4e330&v=4 url: https://github.com/Kludex -YuriiMotov: - login: YuriiMotov - count: 46 - avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=b9b13d598dddfab529a52d264df80a900bfe7060&v=4 - url: https://github.com/YuriiMotov komtaki: login: komtaki count: 45 avatarUrl: https://avatars.githubusercontent.com/u/39375566?u=260ad6b1a4b34c07dbfa728da5e586f16f6d1824&v=4 url: https://github.com/komtaki +svlandeg: + login: svlandeg + count: 43 + avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4 + url: https://github.com/svlandeg rostik1410: login: rostik1410 count: 42 avatarUrl: https://avatars.githubusercontent.com/u/11443899?u=e26a635c2ba220467b308a326a579b8ccf4a8701&v=4 url: https://github.com/rostik1410 -svlandeg: - login: svlandeg - count: 42 - avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4 - url: https://github.com/svlandeg alperiox: login: alperiox count: 42 @@ -136,7 +136,7 @@ JavierSanchezCastro: alejsdev: login: alejsdev count: 37 - avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=85ceac49fb87138aebe8d663912e359447329090&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=0facffe3abf87f57a1f05fa773d1119cc5c2f6a5&v=4 url: https://github.com/alejsdev mezgoodle: login: mezgoodle @@ -383,6 +383,11 @@ Joao-Pedro-P-Holanda: count: 16 avatarUrl: https://avatars.githubusercontent.com/u/110267046?u=331bd016326dac4cf3df4848f6db2dbbf8b5f978&v=4 url: https://github.com/Joao-Pedro-P-Holanda +maru0123-2004: + login: maru0123-2004 + count: 16 + avatarUrl: https://avatars.githubusercontent.com/u/43961566?u=16ed8603a4d6a4665cb6c53a7aece6f31379b769&v=4 + url: https://github.com/maru0123-2004 JaeHyuckSa: login: JaeHyuckSa count: 16 @@ -418,11 +423,6 @@ mattkoehne: count: 14 avatarUrl: https://avatars.githubusercontent.com/u/80362153?v=4 url: https://github.com/mattkoehne -maru0123-2004: - login: maru0123-2004 - count: 14 - avatarUrl: https://avatars.githubusercontent.com/u/43961566?u=16ed8603a4d6a4665cb6c53a7aece6f31379b769&v=4 - url: https://github.com/maru0123-2004 jovicon: login: jovicon count: 13 @@ -458,6 +458,11 @@ wesinalves: count: 13 avatarUrl: https://avatars.githubusercontent.com/u/13563128?u=9eb17ed50645dd684bfec47e75dba4e9772ec9c1&v=4 url: https://github.com/wesinalves +andersonrocha0: + login: andersonrocha0 + count: 13 + avatarUrl: https://avatars.githubusercontent.com/u/22346169?u=93a1359c8c5461d894802c0cc65bcd09217e7a02&v=4 + url: https://github.com/andersonrocha0 NastasiaSaby: login: NastasiaSaby count: 12 @@ -471,7 +476,7 @@ oandersonmagalhaes: mkdir700: login: mkdir700 count: 12 - avatarUrl: https://avatars.githubusercontent.com/u/56359329?u=3d6ea8714f5000829b60dcf7b13a75b1e73aaf47&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/56359329?u=818e5f4b4dcc1a6ffb3e5aaa08fd827e5a726dfd&v=4 url: https://github.com/mkdir700 batlopes: login: batlopes @@ -493,11 +498,6 @@ KaniKim: count: 12 avatarUrl: https://avatars.githubusercontent.com/u/19832624?u=296dbdd490e0eb96e3d45a2608c065603b17dc31&v=4 url: https://github.com/KaniKim -andersonrocha0: - login: andersonrocha0 - count: 12 - avatarUrl: https://avatars.githubusercontent.com/u/22346169?u=93a1359c8c5461d894802c0cc65bcd09217e7a02&v=4 - url: https://github.com/andersonrocha0 gitgernit: login: gitgernit count: 12 @@ -558,6 +558,11 @@ Zhongheng-Cheng: count: 11 avatarUrl: https://avatars.githubusercontent.com/u/95612344?u=a0f7730a3cc7486827965e01a119ad610bda4b0a&v=4 url: https://github.com/Zhongheng-Cheng +Pyth3rEx: + login: Pyth3rEx + count: 11 + avatarUrl: https://avatars.githubusercontent.com/u/26427764?u=087724f74d813c95925d51e354554bd4b6d6bb60&v=4 + url: https://github.com/Pyth3rEx mariacamilagl: login: mariacamilagl count: 10 @@ -611,7 +616,7 @@ socket-socket: nick-cjyx9: login: nick-cjyx9 count: 10 - avatarUrl: https://avatars.githubusercontent.com/u/119087246?u=7227a2de948c68fb8396d5beff1ee5b0e057c42e&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/119087246?u=3d51dcbd79222ecb6538642f31dc7c8bb708d191&v=4 url: https://github.com/nick-cjyx9 marcelomarkus: login: marcelomarkus @@ -683,11 +688,6 @@ Yarous: count: 9 avatarUrl: https://avatars.githubusercontent.com/u/61277193?u=5b462347458a373b2d599c6f416d2b75eddbffad&v=4 url: https://github.com/Yarous -Pyth3rEx: - login: Pyth3rEx - count: 9 - avatarUrl: https://avatars.githubusercontent.com/u/26427764?u=087724f74d813c95925d51e354554bd4b6d6bb60&v=4 - url: https://github.com/Pyth3rEx dimaqq: login: dimaqq count: 8 @@ -736,7 +736,7 @@ minaton-ru: sungchan1: login: sungchan1 count: 8 - avatarUrl: https://avatars.githubusercontent.com/u/28076127?u=a816d86ef3e60450a7225f128caf9a394c9320f9&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/28076127?u=fadbf24840186aca639d344bb3e0ecf7ff3441cf&v=4 url: https://github.com/sungchan1 Serrones: login: Serrones @@ -761,7 +761,7 @@ anthonycepeda: fabioueno: login: fabioueno count: 7 - avatarUrl: https://avatars.githubusercontent.com/u/14273852?u=edd700982b16317ac6ebfd24c47bc0029b21d360&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/14273852?u=a3d546449cdc96621c32bcc26cf74be6e4390209&v=4 url: https://github.com/fabioueno cfraboulet: login: cfraboulet @@ -793,6 +793,11 @@ Zerohertz: count: 7 avatarUrl: https://avatars.githubusercontent.com/u/42334717?u=5ebf4d33e73b1ad373154f6cdee44f7cab4d05ba&v=4 url: https://github.com/Zerohertz +EdmilsonRodrigues: + login: EdmilsonRodrigues + count: 7 + avatarUrl: https://avatars.githubusercontent.com/u/62777025?u=217d6f3cd6cc750bb8818a3af7726c8d74eb7c2d&v=4 + url: https://github.com/EdmilsonRodrigues deniscapeto: login: deniscapeto count: 6 @@ -1028,11 +1033,6 @@ devluisrodrigues: count: 5 avatarUrl: https://avatars.githubusercontent.com/u/21125286?v=4 url: https://github.com/11kkw -EdmilsonRodrigues: - login: EdmilsonRodrigues - count: 5 - avatarUrl: https://avatars.githubusercontent.com/u/62777025?u=217d6f3cd6cc750bb8818a3af7726c8d74eb7c2d&v=4 - url: https://github.com/EdmilsonRodrigues lpdswing: login: lpdswing count: 4 @@ -1178,6 +1178,11 @@ SBillion: count: 4 avatarUrl: https://avatars.githubusercontent.com/u/1070649?u=3ab493dfc88b39da0eb1600e3b8e7df1c90a5dee&v=4 url: https://github.com/SBillion +seuthootDev: + login: seuthootDev + count: 4 + avatarUrl: https://avatars.githubusercontent.com/u/175179350?u=7c2cbc48ab43b52e0c86592111d92e013d72ea4d&v=4 + url: https://github.com/seuthootDev tyronedamasceno: login: tyronedamasceno count: 3 @@ -1266,7 +1271,7 @@ rafsaf: frnsimoes: login: frnsimoes count: 3 - avatarUrl: https://avatars.githubusercontent.com/u/66239468?u=fd8d408946633acc4bea057c207e6c0833871527&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/66239468?u=cba345870d8d6b25dd6d56ee18f7120581e3c573&v=4 url: https://github.com/frnsimoes lieryan: login: lieryan @@ -1593,6 +1598,11 @@ ayr-ton: count: 2 avatarUrl: https://avatars.githubusercontent.com/u/1090517?u=5cf70a0e0f0dbf084e074e494aa94d7c91a46ba6&v=4 url: https://github.com/ayr-ton +Kadermiyanyedi: + login: Kadermiyanyedi + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/48386782?u=e34f31bf50a8ed8d37fbfa4f301b0c190b1b4b86&v=4 + url: https://github.com/Kadermiyanyedi raphaelauv: login: raphaelauv count: 2 @@ -1831,7 +1841,7 @@ EgorOnishchuk: iamantonreznik: login: iamantonreznik count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/112612414?u=bf6de9a1ab17326fe14de0709719fff3826526d0&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/112612414?u=b9ba8d9b4d3940198bc3a4353dfce70c044a39b1&v=4 url: https://github.com/iamantonreznik Azazul123: login: Azazul123 @@ -1851,7 +1861,7 @@ NavesSapnis: isgin01: login: isgin01 count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/157279130?u=ddffde10876b50f35dc90d1337f507a630530a6a&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/157279130?u=16d6466476cf7dbc55a4cd575b6ea920ebdd81e1&v=4 url: https://github.com/isgin01 syedasamina56: login: syedasamina56 diff --git a/docs/en/data/translators.yml b/docs/en/data/translators.yml index 940b128da..dd5900a41 100644 --- a/docs/en/data/translators.yml +++ b/docs/en/data/translators.yml @@ -8,9 +8,14 @@ jaystone776: count: 46 avatarUrl: https://avatars.githubusercontent.com/u/11191137?u=299205a95e9b6817a43144a48b643346a5aac5cc&v=4 url: https://github.com/jaystone776 +tiangolo: + login: tiangolo + count: 31 + avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4 + url: https://github.com/tiangolo ceb10n: login: ceb10n - count: 29 + count: 30 avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4 url: https://github.com/ceb10n valentinDruzhinin: @@ -28,11 +33,6 @@ SwftAlpc: count: 23 avatarUrl: https://avatars.githubusercontent.com/u/52768429?u=6a3aa15277406520ad37f6236e89466ed44bc5b8&v=4 url: https://github.com/SwftAlpc -tiangolo: - login: tiangolo - count: 22 - avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4 - url: https://github.com/tiangolo hasansezertasan: login: hasansezertasan count: 22 @@ -43,16 +43,16 @@ waynerv: count: 20 avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4 url: https://github.com/waynerv +hard-coders: + login: hard-coders + count: 16 + avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=78d12d1acdf853c817700145e73de7fd9e5d068b&v=4 + url: https://github.com/hard-coders AlertRED: login: AlertRED count: 16 avatarUrl: https://avatars.githubusercontent.com/u/15695000?u=f5a4944c6df443030409c88da7d7fa0b7ead985c&v=4 url: https://github.com/AlertRED -hard-coders: - login: hard-coders - count: 15 - avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=78d12d1acdf853c817700145e73de7fd9e5d068b&v=4 - url: https://github.com/hard-coders Joao-Pedro-P-Holanda: login: Joao-Pedro-P-Holanda count: 14 @@ -108,6 +108,11 @@ pablocm83: count: 8 avatarUrl: https://avatars.githubusercontent.com/u/28315068?u=3310fbb05bb8bfc50d2c48b6cb64ac9ee4a14549&v=4 url: https://github.com/pablocm83 +YuriiMotov: + login: YuriiMotov + count: 8 + avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=bc48be95c429989224786106b027f3c5e40cc354&v=4 + url: https://github.com/YuriiMotov ptt3199: login: ptt3199 count: 7 @@ -133,11 +138,6 @@ Alexandrhub: count: 6 avatarUrl: https://avatars.githubusercontent.com/u/119126536?u=9fc0d48f3307817bafecc5861eb2168401a6cb04&v=4 url: https://github.com/Alexandrhub -YuriiMotov: - login: YuriiMotov - count: 6 - avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=b9b13d598dddfab529a52d264df80a900bfe7060&v=4 - url: https://github.com/YuriiMotov Serrones: login: Serrones count: 5 @@ -291,7 +291,7 @@ hsuanchi: alejsdev: login: alejsdev count: 3 - avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=85ceac49fb87138aebe8d663912e359447329090&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=0facffe3abf87f57a1f05fa773d1119cc5c2f6a5&v=4 url: https://github.com/alejsdev riroan: login: riroan @@ -361,7 +361,7 @@ Rishat-F: ruzia: login: ruzia count: 3 - avatarUrl: https://avatars.githubusercontent.com/u/24503?v=4 + avatarUrl: https://avatars.githubusercontent.com/u/24503?u=abce66d26c9611818720f11e6ae6773a6e0928f8&v=4 url: https://github.com/ruzia izaguerreiro: login: izaguerreiro @@ -413,6 +413,11 @@ ayr-ton: count: 2 avatarUrl: https://avatars.githubusercontent.com/u/1090517?u=5cf70a0e0f0dbf084e074e494aa94d7c91a46ba6&v=4 url: https://github.com/ayr-ton +Kadermiyanyedi: + login: Kadermiyanyedi + count: 2 + avatarUrl: https://avatars.githubusercontent.com/u/48386782?u=e34f31bf50a8ed8d37fbfa4f301b0c190b1b4b86&v=4 + url: https://github.com/Kadermiyanyedi KdHyeon0661: login: KdHyeon0661 count: 2 @@ -461,7 +466,7 @@ ArtemKhymenko: hasnatsajid: login: hasnatsajid count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/86589885?u=6668823c3b029bfecf10a8918ed3af1aafb8b15e&v=4 + avatarUrl: https://avatars.githubusercontent.com/u/86589885?v=4 url: https://github.com/hasnatsajid alperiox: login: alperiox From 779f7ddc37e1e03e199cf5b243e4d5d3c5f7c4e8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 2 Feb 2026 10:24:48 +0000 Subject: [PATCH 04/56] =?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 699b96696..0fe3eebf9 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -41,6 +41,7 @@ hide: ### Internal +* 👥 Update FastAPI People - Contributors and Translators. PR [#14796](https://github.com/fastapi/fastapi/pull/14796) by [@tiangolo](https://github.com/tiangolo). * 🔧 Ensure that an edit to `uv.lock` gets the `internal` label. PR [#14759](https://github.com/fastapi/fastapi/pull/14759) by [@svlandeg](https://github.com/svlandeg). * 🔧 Update sponsors: remove Requestly. PR [#14735](https://github.com/fastapi/fastapi/pull/14735) by [@tiangolo](https://github.com/tiangolo). * 🔧 Update sponsors, LambdaTest changes to TestMu AI. PR [#14734](https://github.com/fastapi/fastapi/pull/14734) by [@tiangolo](https://github.com/tiangolo). From 20ff394d7540dd560df1e9252584e3965d59b0c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Mon, 2 Feb 2026 02:26:58 -0800 Subject: [PATCH 05/56] =?UTF-8?q?=F0=9F=91=A5=20Update=20FastAPI=20GitHub?= =?UTF-8?q?=20topic=20repositories=20(#14803)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: github-actions[bot] --- docs/en/data/topic_repos.yml | 336 +++++++++++++++++------------------ 1 file changed, 168 insertions(+), 168 deletions(-) diff --git a/docs/en/data/topic_repos.yml b/docs/en/data/topic_repos.yml index d089c7e5a..a37cb6dcf 100644 --- a/docs/en/data/topic_repos.yml +++ b/docs/en/data/topic_repos.yml @@ -1,176 +1,181 @@ - name: full-stack-fastapi-template html_url: https://github.com/fastapi/full-stack-fastapi-template - stars: 40334 + stars: 41312 owner_login: fastapi owner_html_url: https://github.com/fastapi - name: Hello-Python html_url: https://github.com/mouredev/Hello-Python - stars: 33628 + stars: 34206 owner_login: mouredev owner_html_url: https://github.com/mouredev - name: serve html_url: https://github.com/jina-ai/serve - stars: 21817 + stars: 21832 owner_login: jina-ai owner_html_url: https://github.com/jina-ai - name: HivisionIDPhotos html_url: https://github.com/Zeyi-Lin/HivisionIDPhotos - stars: 20409 + stars: 20661 owner_login: Zeyi-Lin owner_html_url: https://github.com/Zeyi-Lin - name: sqlmodel html_url: https://github.com/fastapi/sqlmodel - stars: 17415 + stars: 17567 owner_login: fastapi owner_html_url: https://github.com/fastapi - name: fastapi-best-practices html_url: https://github.com/zhanymkanov/fastapi-best-practices - stars: 15776 + stars: 16291 owner_login: zhanymkanov owner_html_url: https://github.com/zhanymkanov - name: Douyin_TikTok_Download_API html_url: https://github.com/Evil0ctal/Douyin_TikTok_Download_API - stars: 15588 + stars: 16132 owner_login: Evil0ctal owner_html_url: https://github.com/Evil0ctal -- name: machine-learning-zoomcamp - html_url: https://github.com/DataTalksClub/machine-learning-zoomcamp - stars: 12447 - owner_login: DataTalksClub - owner_html_url: https://github.com/DataTalksClub - name: SurfSense html_url: https://github.com/MODSetter/SurfSense - stars: 12128 + stars: 12723 owner_login: MODSetter owner_html_url: https://github.com/MODSetter +- name: machine-learning-zoomcamp + html_url: https://github.com/DataTalksClub/machine-learning-zoomcamp + stars: 12575 + owner_login: DataTalksClub + owner_html_url: https://github.com/DataTalksClub - name: fastapi_mcp html_url: https://github.com/tadata-org/fastapi_mcp - stars: 11326 + stars: 11478 owner_login: tadata-org owner_html_url: https://github.com/tadata-org - name: awesome-fastapi html_url: https://github.com/mjhea0/awesome-fastapi - stars: 10901 + stars: 11018 owner_login: mjhea0 owner_html_url: https://github.com/mjhea0 - name: XHS-Downloader html_url: https://github.com/JoeanAmier/XHS-Downloader - stars: 9584 + stars: 9938 owner_login: JoeanAmier owner_html_url: https://github.com/JoeanAmier - name: polar html_url: https://github.com/polarsource/polar - stars: 8951 + stars: 9348 owner_login: polarsource owner_html_url: https://github.com/polarsource - name: FastUI html_url: https://github.com/pydantic/FastUI - stars: 8934 + stars: 8949 owner_login: pydantic owner_html_url: https://github.com/pydantic - name: FileCodeBox html_url: https://github.com/vastsa/FileCodeBox - stars: 7934 + stars: 8060 owner_login: vastsa owner_html_url: https://github.com/vastsa - name: nonebot2 html_url: https://github.com/nonebot/nonebot2 - stars: 7248 + stars: 7311 owner_login: nonebot owner_html_url: https://github.com/nonebot - name: hatchet html_url: https://github.com/hatchet-dev/hatchet - stars: 6392 + stars: 6479 owner_login: hatchet-dev owner_html_url: https://github.com/hatchet-dev - name: fastapi-users html_url: https://github.com/fastapi-users/fastapi-users - stars: 5899 + stars: 5970 owner_login: fastapi-users owner_html_url: https://github.com/fastapi-users - name: serge html_url: https://github.com/serge-chat/serge - stars: 5754 + stars: 5751 owner_login: serge-chat owner_html_url: https://github.com/serge-chat - name: strawberry html_url: https://github.com/strawberry-graphql/strawberry - stars: 4577 + stars: 4598 owner_login: strawberry-graphql owner_html_url: https://github.com/strawberry-graphql +- name: devpush + html_url: https://github.com/hunvreus/devpush + stars: 4407 + owner_login: hunvreus + owner_html_url: https://github.com/hunvreus +- name: Kokoro-FastAPI + html_url: https://github.com/remsky/Kokoro-FastAPI + stars: 4359 + owner_login: remsky + owner_html_url: https://github.com/remsky - name: poem html_url: https://github.com/poem-web/poem - stars: 4303 + stars: 4337 owner_login: poem-web owner_html_url: https://github.com/poem-web - name: chatgpt-web-share html_url: https://github.com/chatpire/chatgpt-web-share - stars: 4287 + stars: 4279 owner_login: chatpire owner_html_url: https://github.com/chatpire - name: dynaconf html_url: https://github.com/dynaconf/dynaconf - stars: 4221 + stars: 4244 owner_login: dynaconf owner_html_url: https://github.com/dynaconf -- name: Kokoro-FastAPI - html_url: https://github.com/remsky/Kokoro-FastAPI - stars: 4181 - owner_login: remsky - owner_html_url: https://github.com/remsky +- name: Yuxi-Know + html_url: https://github.com/xerrors/Yuxi-Know + stars: 4154 + owner_login: xerrors + owner_html_url: https://github.com/xerrors - name: atrilabs-engine html_url: https://github.com/Atri-Labs/atrilabs-engine - stars: 4090 + stars: 4086 owner_login: Atri-Labs owner_html_url: https://github.com/Atri-Labs -- name: devpush - html_url: https://github.com/hunvreus/devpush - stars: 4037 - owner_login: hunvreus - owner_html_url: https://github.com/hunvreus - name: logfire html_url: https://github.com/pydantic/logfire - stars: 3896 + stars: 3975 owner_login: pydantic owner_html_url: https://github.com/pydantic - name: LitServe html_url: https://github.com/Lightning-AI/LitServe - stars: 3756 + stars: 3797 owner_login: Lightning-AI owner_html_url: https://github.com/Lightning-AI - name: huma html_url: https://github.com/danielgtaylor/huma - stars: 3702 + stars: 3785 owner_login: danielgtaylor owner_html_url: https://github.com/danielgtaylor -- name: Yuxi-Know - html_url: https://github.com/xerrors/Yuxi-Know - stars: 3680 - owner_login: xerrors - owner_html_url: https://github.com/xerrors - name: datamodel-code-generator html_url: https://github.com/koxudaxi/datamodel-code-generator - stars: 3675 + stars: 3731 owner_login: koxudaxi owner_html_url: https://github.com/koxudaxi - name: fastapi-admin html_url: https://github.com/fastapi-admin/fastapi-admin - stars: 3659 + stars: 3697 owner_login: fastapi-admin owner_html_url: https://github.com/fastapi-admin - name: farfalle html_url: https://github.com/rashadphz/farfalle - stars: 3497 + stars: 3506 owner_login: rashadphz owner_html_url: https://github.com/rashadphz - name: tracecat html_url: https://github.com/TracecatHQ/tracecat - stars: 3421 + stars: 3458 owner_login: TracecatHQ owner_html_url: https://github.com/TracecatHQ +- name: mcp-context-forge + html_url: https://github.com/IBM/mcp-context-forge + stars: 3216 + owner_login: IBM + owner_html_url: https://github.com/IBM - name: opyrator html_url: https://github.com/ml-tooling/opyrator - stars: 3136 + stars: 3134 owner_login: ml-tooling owner_html_url: https://github.com/ml-tooling - name: docarray @@ -180,316 +185,311 @@ owner_html_url: https://github.com/docarray - name: fastapi-realworld-example-app html_url: https://github.com/nsidnev/fastapi-realworld-example-app - stars: 3051 + stars: 3072 owner_login: nsidnev owner_html_url: https://github.com/nsidnev -- name: mcp-context-forge - html_url: https://github.com/IBM/mcp-context-forge - stars: 3034 - owner_login: IBM - owner_html_url: https://github.com/IBM - name: uvicorn-gunicorn-fastapi-docker html_url: https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker - stars: 2904 + stars: 2908 owner_login: tiangolo owner_html_url: https://github.com/tiangolo - name: FastAPI-template html_url: https://github.com/s3rius/FastAPI-template - stars: 2680 + stars: 2728 owner_login: s3rius owner_html_url: https://github.com/s3rius - name: best-of-web-python html_url: https://github.com/ml-tooling/best-of-web-python - stars: 2662 + stars: 2686 owner_login: ml-tooling owner_html_url: https://github.com/ml-tooling - name: YC-Killer html_url: https://github.com/sahibzada-allahyar/YC-Killer - stars: 2614 + stars: 2648 owner_login: sahibzada-allahyar owner_html_url: https://github.com/sahibzada-allahyar - name: sqladmin html_url: https://github.com/aminalaee/sqladmin - stars: 2587 + stars: 2637 owner_login: aminalaee owner_html_url: https://github.com/aminalaee - name: fastapi-react html_url: https://github.com/Buuntu/fastapi-react - stars: 2566 + stars: 2573 owner_login: Buuntu owner_html_url: https://github.com/Buuntu - name: RasaGPT html_url: https://github.com/paulpierre/RasaGPT - stars: 2456 + stars: 2460 owner_login: paulpierre owner_html_url: https://github.com/paulpierre - name: supabase-py html_url: https://github.com/supabase/supabase-py - stars: 2394 + stars: 2428 owner_login: supabase owner_html_url: https://github.com/supabase +- name: 30-Days-of-Python + html_url: https://github.com/codingforentrepreneurs/30-Days-of-Python + stars: 2347 + owner_login: codingforentrepreneurs + owner_html_url: https://github.com/codingforentrepreneurs - name: nextpy html_url: https://github.com/dot-agent/nextpy - stars: 2338 + stars: 2337 owner_login: dot-agent owner_html_url: https://github.com/dot-agent - name: fastapi-utils html_url: https://github.com/fastapiutils/fastapi-utils - stars: 2289 + stars: 2299 owner_login: fastapiutils owner_html_url: https://github.com/fastapiutils - name: langserve html_url: https://github.com/langchain-ai/langserve - stars: 2234 + stars: 2255 owner_login: langchain-ai owner_html_url: https://github.com/langchain-ai -- name: 30-Days-of-Python - html_url: https://github.com/codingforentrepreneurs/30-Days-of-Python - stars: 2232 - owner_login: codingforentrepreneurs - owner_html_url: https://github.com/codingforentrepreneurs +- name: NoteDiscovery + html_url: https://github.com/gamosoft/NoteDiscovery + stars: 2182 + owner_login: gamosoft + owner_html_url: https://github.com/gamosoft - name: solara html_url: https://github.com/widgetti/solara - stars: 2141 + stars: 2154 owner_login: widgetti owner_html_url: https://github.com/widgetti - name: mangum html_url: https://github.com/Kludex/mangum - stars: 2046 + stars: 2071 owner_login: Kludex owner_html_url: https://github.com/Kludex - name: fastapi_best_architecture html_url: https://github.com/fastapi-practices/fastapi_best_architecture - stars: 1963 + stars: 2036 owner_login: fastapi-practices owner_html_url: https://github.com/fastapi-practices -- name: NoteDiscovery - html_url: https://github.com/gamosoft/NoteDiscovery - stars: 1943 - owner_login: gamosoft - owner_html_url: https://github.com/gamosoft -- name: agentkit - html_url: https://github.com/BCG-X-Official/agentkit - stars: 1936 - owner_login: BCG-X-Official - owner_html_url: https://github.com/BCG-X-Official - name: vue-fastapi-admin html_url: https://github.com/mizhexiaoxiao/vue-fastapi-admin - stars: 1909 + stars: 1983 owner_login: mizhexiaoxiao owner_html_url: https://github.com/mizhexiaoxiao -- name: manage-fastapi - html_url: https://github.com/ycd/manage-fastapi - stars: 1887 - owner_login: ycd - owner_html_url: https://github.com/ycd +- name: agentkit + html_url: https://github.com/BCG-X-Official/agentkit + stars: 1941 + owner_login: BCG-X-Official + owner_html_url: https://github.com/BCG-X-Official +- name: fastapi-langgraph-agent-production-ready-template + html_url: https://github.com/wassim249/fastapi-langgraph-agent-production-ready-template + stars: 1920 + owner_login: wassim249 + owner_html_url: https://github.com/wassim249 - name: openapi-python-client html_url: https://github.com/openapi-generators/openapi-python-client - stars: 1879 + stars: 1900 owner_login: openapi-generators owner_html_url: https://github.com/openapi-generators +- name: manage-fastapi + html_url: https://github.com/ycd/manage-fastapi + stars: 1894 + owner_login: ycd + owner_html_url: https://github.com/ycd - name: slowapi html_url: https://github.com/laurentS/slowapi - stars: 1845 + stars: 1891 owner_login: laurentS owner_html_url: https://github.com/laurentS - name: piccolo html_url: https://github.com/piccolo-orm/piccolo - stars: 1843 + stars: 1854 owner_login: piccolo-orm owner_html_url: https://github.com/piccolo-orm +- name: fastapi-cache + html_url: https://github.com/long2ice/fastapi-cache + stars: 1816 + owner_login: long2ice + owner_html_url: https://github.com/long2ice - name: python-week-2022 html_url: https://github.com/rochacbruno/python-week-2022 stars: 1813 owner_login: rochacbruno owner_html_url: https://github.com/rochacbruno -- name: fastapi-cache - html_url: https://github.com/long2ice/fastapi-cache - stars: 1805 - owner_login: long2ice - owner_html_url: https://github.com/long2ice - name: ormar html_url: https://github.com/collerek/ormar - stars: 1785 + stars: 1797 owner_login: collerek owner_html_url: https://github.com/collerek -- name: fastapi-langgraph-agent-production-ready-template - html_url: https://github.com/wassim249/fastapi-langgraph-agent-production-ready-template - stars: 1780 - owner_login: wassim249 - owner_html_url: https://github.com/wassim249 - name: FastAPI-boilerplate html_url: https://github.com/benavlabs/FastAPI-boilerplate - stars: 1734 + stars: 1792 owner_login: benavlabs owner_html_url: https://github.com/benavlabs - name: termpair html_url: https://github.com/cs01/termpair - stars: 1724 + stars: 1727 owner_login: cs01 owner_html_url: https://github.com/cs01 - name: fastapi-crudrouter html_url: https://github.com/awtkns/fastapi-crudrouter - stars: 1671 + stars: 1677 owner_login: awtkns owner_html_url: https://github.com/awtkns - name: langchain-serve html_url: https://github.com/jina-ai/langchain-serve - stars: 1633 + stars: 1634 owner_login: jina-ai owner_html_url: https://github.com/jina-ai - name: fastapi-pagination html_url: https://github.com/uriyyo/fastapi-pagination - stars: 1588 + stars: 1607 owner_login: uriyyo owner_html_url: https://github.com/uriyyo - name: awesome-fastapi-projects html_url: https://github.com/Kludex/awesome-fastapi-projects - stars: 1583 + stars: 1592 owner_login: Kludex owner_html_url: https://github.com/Kludex -- name: coronavirus-tracker-api - html_url: https://github.com/ExpDev07/coronavirus-tracker-api - stars: 1571 - owner_login: ExpDev07 - owner_html_url: https://github.com/ExpDev07 - name: bracket html_url: https://github.com/evroon/bracket - stars: 1549 + stars: 1580 owner_login: evroon owner_html_url: https://github.com/evroon +- name: coronavirus-tracker-api + html_url: https://github.com/ExpDev07/coronavirus-tracker-api + stars: 1570 + owner_login: ExpDev07 + owner_html_url: https://github.com/ExpDev07 - name: fastapi-amis-admin html_url: https://github.com/amisadmin/fastapi-amis-admin - stars: 1491 + stars: 1512 owner_login: amisadmin owner_html_url: https://github.com/amisadmin -- name: fastapi-boilerplate - html_url: https://github.com/teamhide/fastapi-boilerplate - stars: 1452 - owner_login: teamhide - owner_html_url: https://github.com/teamhide - name: fastcrud html_url: https://github.com/benavlabs/fastcrud - stars: 1452 + stars: 1471 owner_login: benavlabs owner_html_url: https://github.com/benavlabs +- name: fastapi-boilerplate + html_url: https://github.com/teamhide/fastapi-boilerplate + stars: 1461 + owner_login: teamhide + owner_html_url: https://github.com/teamhide - name: awesome-python-resources html_url: https://github.com/DjangoEx/awesome-python-resources - stars: 1430 + stars: 1435 owner_login: DjangoEx owner_html_url: https://github.com/DjangoEx - name: prometheus-fastapi-instrumentator html_url: https://github.com/trallnag/prometheus-fastapi-instrumentator - stars: 1399 + stars: 1417 owner_login: trallnag owner_html_url: https://github.com/trallnag - name: fastapi-code-generator html_url: https://github.com/koxudaxi/fastapi-code-generator - stars: 1371 + stars: 1382 owner_login: koxudaxi owner_html_url: https://github.com/koxudaxi +- name: fastapi-scaff + html_url: https://github.com/atpuxiner/fastapi-scaff + stars: 1367 + owner_login: atpuxiner + owner_html_url: https://github.com/atpuxiner - name: fastapi-tutorial html_url: https://github.com/liaogx/fastapi-tutorial - stars: 1346 + stars: 1360 owner_login: liaogx owner_html_url: https://github.com/liaogx - name: budgetml html_url: https://github.com/ebhy/budgetml - stars: 1345 + stars: 1343 owner_login: ebhy owner_html_url: https://github.com/ebhy -- name: fastapi-scaff - html_url: https://github.com/atpuxiner/fastapi-scaff - stars: 1331 - owner_login: atpuxiner - owner_html_url: https://github.com/atpuxiner - name: bolt-python html_url: https://github.com/slackapi/bolt-python - stars: 1266 + stars: 1276 owner_login: slackapi owner_html_url: https://github.com/slackapi - name: bedrock-chat html_url: https://github.com/aws-samples/bedrock-chat - stars: 1266 + stars: 1268 owner_login: aws-samples owner_html_url: https://github.com/aws-samples - name: fastapi-alembic-sqlmodel-async - html_url: https://github.com/jonra1993/fastapi-alembic-sqlmodel-async - stars: 1260 - owner_login: jonra1993 - owner_html_url: https://github.com/jonra1993 + html_url: https://github.com/vargasjona/fastapi-alembic-sqlmodel-async + stars: 1265 + owner_login: vargasjona + owner_html_url: https://github.com/vargasjona - name: fastapi_production_template html_url: https://github.com/zhanymkanov/fastapi_production_template - stars: 1222 + stars: 1227 owner_login: zhanymkanov owner_html_url: https://github.com/zhanymkanov -- name: langchain-extract - html_url: https://github.com/langchain-ai/langchain-extract - stars: 1179 - owner_login: langchain-ai - owner_html_url: https://github.com/langchain-ai - name: restish html_url: https://github.com/rest-sh/restish - stars: 1152 + stars: 1200 owner_login: rest-sh owner_html_url: https://github.com/rest-sh +- name: langchain-extract + html_url: https://github.com/langchain-ai/langchain-extract + stars: 1183 + owner_login: langchain-ai + owner_html_url: https://github.com/langchain-ai - name: odmantic html_url: https://github.com/art049/odmantic - stars: 1143 + stars: 1162 owner_login: art049 owner_html_url: https://github.com/art049 -- name: authx - html_url: https://github.com/yezz123/authx - stars: 1128 - owner_login: yezz123 - owner_html_url: https://github.com/yezz123 -- name: SAG - html_url: https://github.com/Zleap-AI/SAG - stars: 1104 - owner_login: Zleap-AI - owner_html_url: https://github.com/Zleap-AI - name: aktools html_url: https://github.com/akfamily/aktools - stars: 1072 + stars: 1155 owner_login: akfamily owner_html_url: https://github.com/akfamily - name: RuoYi-Vue3-FastAPI html_url: https://github.com/insistence/RuoYi-Vue3-FastAPI - stars: 1063 + stars: 1155 owner_login: insistence owner_html_url: https://github.com/insistence +- name: authx + html_url: https://github.com/yezz123/authx + stars: 1142 + owner_login: yezz123 + owner_html_url: https://github.com/yezz123 +- name: SAG + html_url: https://github.com/Zleap-AI/SAG + stars: 1110 + owner_login: Zleap-AI + owner_html_url: https://github.com/Zleap-AI - name: flock html_url: https://github.com/Onelevenvy/flock - stars: 1059 + stars: 1069 owner_login: Onelevenvy owner_html_url: https://github.com/Onelevenvy - name: fastapi-observability html_url: https://github.com/blueswen/fastapi-observability - stars: 1046 + stars: 1063 owner_login: blueswen owner_html_url: https://github.com/blueswen - name: enterprise-deep-research html_url: https://github.com/SalesforceAIResearch/enterprise-deep-research - stars: 1019 + stars: 1061 owner_login: SalesforceAIResearch owner_html_url: https://github.com/SalesforceAIResearch - name: titiler html_url: https://github.com/developmentseed/titiler - stars: 1016 + stars: 1039 owner_login: developmentseed owner_html_url: https://github.com/developmentseed - name: every-pdf html_url: https://github.com/DDULDDUCK/every-pdf - stars: 1004 + stars: 1017 owner_login: DDULDDUCK owner_html_url: https://github.com/DDULDDUCK - name: autollm html_url: https://github.com/viddexa/autollm - stars: 1003 + stars: 1005 owner_login: viddexa owner_html_url: https://github.com/viddexa - name: lanarky html_url: https://github.com/ajndkr/lanarky - stars: 996 + stars: 995 owner_login: ajndkr owner_html_url: https://github.com/ajndkr From 6173733200c3498408942a86792871b245dec032 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 2 Feb 2026 10:27:24 +0000 Subject: [PATCH 06/56] =?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 0fe3eebf9..8f8edd5f6 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -41,6 +41,7 @@ hide: ### Internal +* 👥 Update FastAPI GitHub topic repositories. PR [#14803](https://github.com/fastapi/fastapi/pull/14803) by [@tiangolo](https://github.com/tiangolo). * 👥 Update FastAPI People - Contributors and Translators. PR [#14796](https://github.com/fastapi/fastapi/pull/14796) by [@tiangolo](https://github.com/tiangolo). * 🔧 Ensure that an edit to `uv.lock` gets the `internal` label. PR [#14759](https://github.com/fastapi/fastapi/pull/14759) by [@svlandeg](https://github.com/svlandeg). * 🔧 Update sponsors: remove Requestly. PR [#14735](https://github.com/fastapi/fastapi/pull/14735) by [@tiangolo](https://github.com/tiangolo). From b833e53ade85dcb330145ac6e95a5b7c74a78fcd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Feb 2026 15:54:49 +0100 Subject: [PATCH 07/56] =?UTF-8?q?=E2=AC=86=20Bump=20typer=20from=200.16.0?= =?UTF-8?q?=20to=200.21.1=20(#14799)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [typer](https://github.com/fastapi/typer) from 0.16.0 to 0.21.1. - [Release notes](https://github.com/fastapi/typer/releases) - [Changelog](https://github.com/fastapi/typer/blob/master/docs/release-notes.md) - [Commits](https://github.com/fastapi/typer/compare/0.16.0...0.21.1) --- updated-dependencies: - dependency-name: typer dependency-version: 0.21.1 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Sofie Van Landeghem --- pyproject.toml | 2 +- uv.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index fe9b3a7ea..b104eed80 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -147,7 +147,7 @@ docs = [ "pillow==11.3.0", "python-slugify==8.0.4", "pyyaml>=5.3.1,<7.0.0", - "typer==0.16.0", + "typer==0.21.1", ] docs-tests = [ "httpx>=0.23.0,<1.0.0", diff --git a/uv.lock b/uv.lock index 9ae2220e0..5cdf5f767 100644 --- a/uv.lock +++ b/uv.lock @@ -1230,7 +1230,7 @@ dev = [ { name = "ruff", specifier = "==0.14.3" }, { name = "sqlmodel", specifier = "==0.0.27" }, { name = "strawberry-graphql", specifier = ">=0.200.0,<1.0.0" }, - { name = "typer", specifier = "==0.16.0" }, + { name = "typer", specifier = "==0.21.1" }, { name = "types-orjson", specifier = "==3.6.2" }, { name = "types-ujson", specifier = "==5.10.0.20240515" }, ] @@ -1251,7 +1251,7 @@ docs = [ { name = "python-slugify", specifier = "==8.0.4" }, { name = "pyyaml", specifier = ">=5.3.1,<7.0.0" }, { name = "ruff", specifier = "==0.14.3" }, - { name = "typer", specifier = "==0.16.0" }, + { name = "typer", specifier = "==0.21.1" }, ] docs-tests = [ { name = "httpx", specifier = ">=0.23.0,<1.0.0" }, @@ -4737,7 +4737,7 @@ wheels = [ [[package]] name = "typer" -version = "0.16.0" +version = "0.21.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click", version = "8.1.8", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, @@ -4746,9 +4746,9 @@ dependencies = [ { name = "shellingham" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c5/8c/7d682431efca5fd290017663ea4588bf6f2c6aad085c7f108c5dbc316e70/typer-0.16.0.tar.gz", hash = "sha256:af377ffaee1dbe37ae9440cb4e8f11686ea5ce4e9bae01b84ae7c63b87f1dd3b", size = 102625, upload-time = "2025-05-26T14:30:31.824Z" } +sdist = { url = "https://files.pythonhosted.org/packages/36/bf/8825b5929afd84d0dabd606c67cd57b8388cb3ec385f7ef19c5cc2202069/typer-0.21.1.tar.gz", hash = "sha256:ea835607cd752343b6b2b7ce676893e5a0324082268b48f27aa058bdb7d2145d", size = 110371, upload-time = "2026-01-06T11:21:10.989Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/42/3efaf858001d2c2913de7f354563e3a3a2f0decae3efe98427125a8f441e/typer-0.16.0-py3-none-any.whl", hash = "sha256:1f79bed11d4d02d4310e3c1b7ba594183bcedb0ac73b27a9e5f28f6fb5b98855", size = 46317, upload-time = "2025-05-26T14:30:30.523Z" }, + { url = "https://files.pythonhosted.org/packages/a0/1d/d9257dd49ff2ca23ea5f132edf1281a0c4f9de8a762b9ae399b670a59235/typer-0.21.1-py3-none-any.whl", hash = "sha256:7985e89081c636b88d172c2ee0cfe33c253160994d47bdfdc302defd7d1f1d01", size = 47381, upload-time = "2026-01-06T11:21:09.824Z" }, ] [[package]] From da4083c30fcd1f4e2a4cc4bb5bb286545d124788 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 2 Feb 2026 14:55:12 +0000 Subject: [PATCH 08/56] =?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 8f8edd5f6..afe456a3f 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -41,6 +41,7 @@ hide: ### Internal +* ⬆ Bump typer from 0.16.0 to 0.21.1. PR [#14799](https://github.com/fastapi/fastapi/pull/14799) by [@dependabot[bot]](https://github.com/apps/dependabot). * 👥 Update FastAPI GitHub topic repositories. PR [#14803](https://github.com/fastapi/fastapi/pull/14803) by [@tiangolo](https://github.com/tiangolo). * 👥 Update FastAPI People - Contributors and Translators. PR [#14796](https://github.com/fastapi/fastapi/pull/14796) by [@tiangolo](https://github.com/tiangolo). * 🔧 Ensure that an edit to `uv.lock` gets the `internal` label. PR [#14759](https://github.com/fastapi/fastapi/pull/14759) by [@svlandeg](https://github.com/svlandeg). From a0e34c747340b5b731a363f6b683fa0d0062ca49 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Feb 2026 15:56:33 +0100 Subject: [PATCH 09/56] =?UTF-8?q?=E2=AC=86=20Bump=20gitpython=20from=203.1?= =?UTF-8?q?.45=20to=203.1.46=20(#14800)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [gitpython](https://github.com/gitpython-developers/GitPython) from 3.1.45 to 3.1.46. - [Release notes](https://github.com/gitpython-developers/GitPython/releases) - [Changelog](https://github.com/gitpython-developers/GitPython/blob/main/CHANGES) - [Commits](https://github.com/gitpython-developers/GitPython/compare/3.1.45...3.1.46) --- updated-dependencies: - dependency-name: gitpython dependency-version: 3.1.46 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Sofie Van Landeghem --- pyproject.toml | 2 +- uv.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b104eed80..39a6bd155 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -180,7 +180,7 @@ tests = [ "types-ujson==5.10.0.20240515", ] translations = [ - "gitpython==3.1.45", + "gitpython==3.1.46", "pydantic-ai==0.4.10", "pygithub==2.8.1", ] diff --git a/uv.lock b/uv.lock index 5cdf5f767..f3a5f8e6d 100644 --- a/uv.lock +++ b/uv.lock @@ -1203,7 +1203,7 @@ dev = [ { name = "coverage", extras = ["toml"], specifier = ">=6.5.0,<8.0" }, { name = "dirty-equals", specifier = "==0.9.0" }, { name = "flask", specifier = ">=1.1.2,<4.0.0" }, - { name = "gitpython", specifier = "==3.1.45" }, + { name = "gitpython", specifier = "==3.1.46" }, { name = "griffe-typingdoc", specifier = "==0.3.0" }, { name = "griffe-warnings-deprecated", specifier = "==1.1.0" }, { name = "httpx", specifier = ">=0.23.0,<1.0.0" }, @@ -1285,7 +1285,7 @@ tests = [ { name = "types-ujson", specifier = "==5.10.0.20240515" }, ] translations = [ - { name = "gitpython", specifier = "==3.1.45" }, + { name = "gitpython", specifier = "==3.1.46" }, { name = "pydantic-ai", specifier = "==0.4.10" }, { name = "pygithub", specifier = "==2.8.1" }, ] @@ -1632,15 +1632,15 @@ wheels = [ [[package]] name = "gitpython" -version = "3.1.45" +version = "3.1.46" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "gitdb" }, { name = "typing-extensions", marker = "python_full_version < '3.10'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9a/c8/dd58967d119baab745caec2f9d853297cec1989ec1d63f677d3880632b88/gitpython-3.1.45.tar.gz", hash = "sha256:85b0ee964ceddf211c41b9f27a49086010a190fd8132a24e21f362a4b36a791c", size = 215076, upload-time = "2025-07-24T03:45:54.871Z" } +sdist = { url = "https://files.pythonhosted.org/packages/df/b5/59d16470a1f0dfe8c793f9ef56fd3826093fc52b3bd96d6b9d6c26c7e27b/gitpython-3.1.46.tar.gz", hash = "sha256:400124c7d0ef4ea03f7310ac2fbf7151e09ff97f2a3288d64a440c584a29c37f", size = 215371, upload-time = "2026-01-01T15:37:32.073Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/01/61/d4b89fec821f72385526e1b9d9a3a0385dda4a72b206d28049e2c7cd39b8/gitpython-3.1.45-py3-none-any.whl", hash = "sha256:8908cb2e02fb3b93b7eb0f2827125cb699869470432cc885f019b8fd0fccff77", size = 208168, upload-time = "2025-07-24T03:45:52.517Z" }, + { url = "https://files.pythonhosted.org/packages/6a/09/e21df6aef1e1ffc0c816f0522ddc3f6dcded766c3261813131c78a704470/gitpython-3.1.46-py3-none-any.whl", hash = "sha256:79812ed143d9d25b6d176a10bb511de0f9c67b1fa641d82097b0ab90398a2058", size = 208620, upload-time = "2026-01-01T15:37:30.574Z" }, ] [[package]] From f2487ce88c4ae8f7e64668409770427b245c3a60 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Feb 2026 15:57:22 +0100 Subject: [PATCH 10/56] =?UTF-8?q?=E2=AC=86=20Bump=20mkdocs-macros-plugin?= =?UTF-8?q?=20from=201.4.1=20to=201.5.0=20(#14801)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [mkdocs-macros-plugin](https://github.com/fralau/mkdocs_macros_plugin) from 1.4.1 to 1.5.0. - [Release notes](https://github.com/fralau/mkdocs_macros_plugin/releases) - [Changelog](https://github.com/fralau/mkdocs-macros-plugin/blob/master/CHANGELOG.md) - [Commits](https://github.com/fralau/mkdocs_macros_plugin/compare/v1.4.1...v1.5.0) --- updated-dependencies: - dependency-name: mkdocs-macros-plugin dependency-version: 1.5.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Sofie Van Landeghem --- pyproject.toml | 2 +- uv.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 39a6bd155..524d52718 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -140,7 +140,7 @@ docs = [ "jieba==0.42.1", "markdown-include-variants==0.0.8", "mdx-include>=1.4.1,<2.0.0", - "mkdocs-macros-plugin==1.4.1", + "mkdocs-macros-plugin==1.5.0", "mkdocs-material==9.7.0", "mkdocs-redirects>=1.2.1,<1.3.0", "mkdocstrings[python]==0.30.1", diff --git a/uv.lock b/uv.lock index f3a5f8e6d..312181b4e 100644 --- a/uv.lock +++ b/uv.lock @@ -1211,7 +1211,7 @@ dev = [ { name = "jieba", specifier = "==0.42.1" }, { name = "markdown-include-variants", specifier = "==0.0.8" }, { name = "mdx-include", specifier = ">=1.4.1,<2.0.0" }, - { name = "mkdocs-macros-plugin", specifier = "==1.4.1" }, + { name = "mkdocs-macros-plugin", specifier = "==1.5.0" }, { name = "mkdocs-material", specifier = "==9.7.0" }, { name = "mkdocs-redirects", specifier = ">=1.2.1,<1.3.0" }, { name = "mkdocstrings", extras = ["python"], specifier = "==0.30.1" }, @@ -1243,7 +1243,7 @@ docs = [ { name = "jieba", specifier = "==0.42.1" }, { name = "markdown-include-variants", specifier = "==0.0.8" }, { name = "mdx-include", specifier = ">=1.4.1,<2.0.0" }, - { name = "mkdocs-macros-plugin", specifier = "==1.4.1" }, + { name = "mkdocs-macros-plugin", specifier = "==1.5.0" }, { name = "mkdocs-material", specifier = "==9.7.0" }, { name = "mkdocs-redirects", specifier = ">=1.2.1,<1.3.0" }, { name = "mkdocstrings", extras = ["python"], specifier = "==0.30.1" }, @@ -2652,7 +2652,7 @@ wheels = [ [[package]] name = "mkdocs-macros-plugin" -version = "1.4.1" +version = "1.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "hjson" }, @@ -2667,9 +2667,9 @@ dependencies = [ { name = "termcolor", version = "3.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, { name = "termcolor", version = "3.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1b/42/bb2ceed148c77f82b57c6d3b7f584f0f34ababf7a9a8ff85809380d1f400/mkdocs_macros_plugin-1.4.1.tar.gz", hash = "sha256:55a9c93871e3744cdeb0736316783d60830a6d5d97b1132364e6b491607f2332", size = 35094, upload-time = "2025-10-25T12:37:20.689Z" } +sdist = { url = "https://files.pythonhosted.org/packages/92/15/e6a44839841ebc9c5872fa0e6fad1c3757424e4fe026093b68e9f386d136/mkdocs_macros_plugin-1.5.0.tar.gz", hash = "sha256:12aa45ce7ecb7a445c66b9f649f3dd05e9b92e8af6bc65e4acd91d26f878c01f", size = 37730, upload-time = "2025-11-13T08:08:55.545Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/93/ec/e6e96a7ae8df414f03f43681821234b0d3b86666f7b91f70ab26775a8809/mkdocs_macros_plugin-1.4.1-py3-none-any.whl", hash = "sha256:5a9e483f6056fe7ad0923802affe699233ca468672e20a9640dba237165b3240", size = 40155, upload-time = "2025-10-25T12:37:19.417Z" }, + { url = "https://files.pythonhosted.org/packages/51/62/9fffba5bb9ed3d31a932ad35038ba9483d59850256ee0fea7f1187173983/mkdocs_macros_plugin-1.5.0-py3-none-any.whl", hash = "sha256:c10fabd812bf50f9170609d0ed518e54f1f0e12c334ac29141723a83c881dd6f", size = 44626, upload-time = "2025-11-13T08:08:53.878Z" }, ] [[package]] From 5c3f0307ae475fd0ceeb47aaa2404119f2b6da8a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Feb 2026 15:57:43 +0100 Subject: [PATCH 11/56] =?UTF-8?q?=E2=AC=86=20Bump=20sqlmodel=20from=200.0.?= =?UTF-8?q?27=20to=200.0.31=20(#14802)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [sqlmodel](https://github.com/fastapi/sqlmodel) from 0.0.27 to 0.0.31. - [Release notes](https://github.com/fastapi/sqlmodel/releases) - [Changelog](https://github.com/fastapi/sqlmodel/blob/main/docs/release-notes.md) - [Commits](https://github.com/fastapi/sqlmodel/compare/0.0.27...0.0.31) --- updated-dependencies: - dependency-name: sqlmodel dependency-version: 0.0.31 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Sofie Van Landeghem --- pyproject.toml | 2 +- uv.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 524d52718..ef4330a0e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -174,7 +174,7 @@ tests = [ "pytest>=7.1.3,<9.0.0", "pytest-codspeed==4.2.0", "pyyaml>=5.3.1,<7.0.0", - "sqlmodel==0.0.27", + "sqlmodel==0.0.31", "strawberry-graphql>=0.200.0,<1.0.0", "types-orjson==3.6.2", "types-ujson==5.10.0.20240515", diff --git a/uv.lock b/uv.lock index 312181b4e..8b202e089 100644 --- a/uv.lock +++ b/uv.lock @@ -1228,7 +1228,7 @@ dev = [ { name = "python-slugify", specifier = "==8.0.4" }, { name = "pyyaml", specifier = ">=5.3.1,<7.0.0" }, { name = "ruff", specifier = "==0.14.3" }, - { name = "sqlmodel", specifier = "==0.0.27" }, + { name = "sqlmodel", specifier = "==0.0.31" }, { name = "strawberry-graphql", specifier = ">=0.200.0,<1.0.0" }, { name = "typer", specifier = "==0.21.1" }, { name = "types-orjson", specifier = "==3.6.2" }, @@ -1279,7 +1279,7 @@ tests = [ { name = "pytest-codspeed", specifier = "==4.2.0" }, { name = "pyyaml", specifier = ">=5.3.1,<7.0.0" }, { name = "ruff", specifier = "==0.14.3" }, - { name = "sqlmodel", specifier = "==0.0.27" }, + { name = "sqlmodel", specifier = "==0.0.31" }, { name = "strawberry-graphql", specifier = ">=0.200.0,<1.0.0" }, { name = "types-orjson", specifier = "==3.6.2" }, { name = "types-ujson", specifier = "==5.10.0.20240515" }, @@ -4415,15 +4415,15 @@ wheels = [ [[package]] name = "sqlmodel" -version = "0.0.27" +version = "0.0.31" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pydantic" }, { name = "sqlalchemy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/90/5a/693d90866233e837d182da76082a6d4c2303f54d3aaaa5c78e1238c5d863/sqlmodel-0.0.27.tar.gz", hash = "sha256:ad1227f2014a03905aef32e21428640848ac09ff793047744a73dfdd077ff620", size = 118053, upload-time = "2025-10-08T16:39:11.938Z" } +sdist = { url = "https://files.pythonhosted.org/packages/56/b8/e7cd6def4a773f25d6e29ffce63ccbfd6cf9488b804ab6fb9b80d334b39d/sqlmodel-0.0.31.tar.gz", hash = "sha256:2d41a8a9ee05e40736e2f9db8ea28cbfe9b5d4e5a18dd139e80605025e0c516c", size = 94952, upload-time = "2025-12-28T12:35:01.436Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8c/92/c35e036151fe53822893979f8a13e6f235ae8191f4164a79ae60a95d66aa/sqlmodel-0.0.27-py3-none-any.whl", hash = "sha256:667fe10aa8ff5438134668228dc7d7a08306f4c5c4c7e6ad3ad68defa0e7aa49", size = 29131, upload-time = "2025-10-08T16:39:10.917Z" }, + { url = "https://files.pythonhosted.org/packages/6c/72/5aa5be921800f6418a949a73c9bb7054890881143e6bc604a93d228a95a3/sqlmodel-0.0.31-py3-none-any.whl", hash = "sha256:6d946d56cac4c2db296ba1541357cee2e795d68174e2043cd138b916794b1513", size = 27093, upload-time = "2025-12-28T12:35:00.108Z" }, ] [[package]] From ecb1444738a3315167a8c11eac9b8503aec5a3d3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 2 Feb 2026 14:57:46 +0000 Subject: [PATCH 12/56] =?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 afe456a3f..997bd98d5 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -41,6 +41,7 @@ hide: ### Internal +* ⬆ Bump gitpython from 3.1.45 to 3.1.46. PR [#14800](https://github.com/fastapi/fastapi/pull/14800) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump typer from 0.16.0 to 0.21.1. PR [#14799](https://github.com/fastapi/fastapi/pull/14799) by [@dependabot[bot]](https://github.com/apps/dependabot). * 👥 Update FastAPI GitHub topic repositories. PR [#14803](https://github.com/fastapi/fastapi/pull/14803) by [@tiangolo](https://github.com/tiangolo). * 👥 Update FastAPI People - Contributors and Translators. PR [#14796](https://github.com/fastapi/fastapi/pull/14796) by [@tiangolo](https://github.com/tiangolo). From 87b5333e8ae48cd68ef90ac29897bce25bb6540c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 2 Feb 2026 15:00:26 +0000 Subject: [PATCH 13/56] =?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 997bd98d5..7fd3b9178 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -41,6 +41,7 @@ hide: ### Internal +* ⬆ Bump mkdocs-macros-plugin from 1.4.1 to 1.5.0. PR [#14801](https://github.com/fastapi/fastapi/pull/14801) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump gitpython from 3.1.45 to 3.1.46. PR [#14800](https://github.com/fastapi/fastapi/pull/14800) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump typer from 0.16.0 to 0.21.1. PR [#14799](https://github.com/fastapi/fastapi/pull/14799) by [@dependabot[bot]](https://github.com/apps/dependabot). * 👥 Update FastAPI GitHub topic repositories. PR [#14803](https://github.com/fastapi/fastapi/pull/14803) by [@tiangolo](https://github.com/tiangolo). From 608ff552ba249c0a6cc8fdf755b43135cd45a9fa Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 2 Feb 2026 15:00:28 +0000 Subject: [PATCH 14/56] =?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 7fd3b9178..fb08caca4 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -41,6 +41,7 @@ hide: ### Internal +* ⬆ Bump sqlmodel from 0.0.27 to 0.0.31. PR [#14802](https://github.com/fastapi/fastapi/pull/14802) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump mkdocs-macros-plugin from 1.4.1 to 1.5.0. PR [#14801](https://github.com/fastapi/fastapi/pull/14801) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump gitpython from 3.1.45 to 3.1.46. PR [#14800](https://github.com/fastapi/fastapi/pull/14800) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump typer from 0.16.0 to 0.21.1. PR [#14799](https://github.com/fastapi/fastapi/pull/14799) by [@dependabot[bot]](https://github.com/apps/dependabot). From bc9ad6b1342bd191693942cbcbd0fee954cf1a3e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Feb 2026 15:09:12 +0000 Subject: [PATCH 15/56] =?UTF-8?q?=E2=AC=86=20Bump=20pyasn1=20from=200.6.1?= =?UTF-8?q?=20to=200.6.2=20(#14804)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [pyasn1](https://github.com/pyasn1/pyasn1) from 0.6.1 to 0.6.2. - [Release notes](https://github.com/pyasn1/pyasn1/releases) - [Changelog](https://github.com/pyasn1/pyasn1/blob/main/CHANGES.rst) - [Commits](https://github.com/pyasn1/pyasn1/compare/v0.6.1...v0.6.2) --- updated-dependencies: - dependency-name: pyasn1 dependency-version: 0.6.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Sofie Van Landeghem --- uv.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/uv.lock b/uv.lock index 8b202e089..3be38bb80 100644 --- a/uv.lock +++ b/uv.lock @@ -3238,11 +3238,11 @@ argon2 = [ [[package]] name = "pyasn1" -version = "0.6.1" +version = "0.6.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ba/e9/01f1a64245b89f039897cb0130016d79f77d52669aae6ee7b159a6c4c018/pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034", size = 145322, upload-time = "2024-09-10T22:41:42.55Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/b6/6e630dff89739fcd427e3f72b3d905ce0acb85a45d4ec3e2678718a3487f/pyasn1-0.6.2.tar.gz", hash = "sha256:9b59a2b25ba7e4f8197db7686c09fb33e658b98339fadb826e9512629017833b", size = 146586, upload-time = "2026-01-16T18:04:18.534Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/f1/d6a797abb14f6283c0ddff96bbdd46937f64122b8c925cab503dd37f8214/pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629", size = 83135, upload-time = "2024-09-11T16:00:36.122Z" }, + { url = "https://files.pythonhosted.org/packages/44/b5/a96872e5184f354da9c84ae119971a0a4c221fe9b27a4d94bd43f2596727/pyasn1-0.6.2-py3-none-any.whl", hash = "sha256:1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf", size = 83371, upload-time = "2026-01-16T18:04:17.174Z" }, ] [[package]] From 82959de14c755e898c4216b2a2d241801c2606eb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 2 Feb 2026 15:09:37 +0000 Subject: [PATCH 16/56] =?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 fb08caca4..0252730c8 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -41,6 +41,7 @@ hide: ### Internal +* ⬆ Bump pyasn1 from 0.6.1 to 0.6.2. PR [#14804](https://github.com/fastapi/fastapi/pull/14804) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump sqlmodel from 0.0.27 to 0.0.31. PR [#14802](https://github.com/fastapi/fastapi/pull/14802) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump mkdocs-macros-plugin from 1.4.1 to 1.5.0. PR [#14801](https://github.com/fastapi/fastapi/pull/14801) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump gitpython from 3.1.45 to 3.1.46. PR [#14800](https://github.com/fastapi/fastapi/pull/14800) by [@dependabot[bot]](https://github.com/apps/dependabot). From ec07e62e1c3c054cd3fa0608708103f2acfc3a03 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Feb 2026 17:34:26 +0100 Subject: [PATCH 17/56] =?UTF-8?q?=E2=AC=86=20Bump=20ruff=20from=200.14.3?= =?UTF-8?q?=20to=200.14.14=20(#14798)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [ruff](https://github.com/astral-sh/ruff) from 0.14.3 to 0.14.14. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.14.3...0.14.14) --- updated-dependencies: - dependency-name: ruff dependency-version: 0.14.14 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Sofie Van Landeghem --- pyproject.toml | 2 +- uv.lock | 52 +++++++++++++++++++++++++------------------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index ef4330a0e..dea61c6a1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -151,7 +151,7 @@ docs = [ ] docs-tests = [ "httpx>=0.23.0,<1.0.0", - "ruff==0.14.3", + "ruff==0.14.14", ] github-actions = [ "httpx>=0.27.0,<1.0.0", diff --git a/uv.lock b/uv.lock index 3be38bb80..2df0b256b 100644 --- a/uv.lock +++ b/uv.lock @@ -1227,7 +1227,7 @@ dev = [ { name = "pytest-codspeed", specifier = "==4.2.0" }, { name = "python-slugify", specifier = "==8.0.4" }, { name = "pyyaml", specifier = ">=5.3.1,<7.0.0" }, - { name = "ruff", specifier = "==0.14.3" }, + { name = "ruff", specifier = "==0.14.14" }, { name = "sqlmodel", specifier = "==0.0.31" }, { name = "strawberry-graphql", specifier = ">=0.200.0,<1.0.0" }, { name = "typer", specifier = "==0.21.1" }, @@ -1250,12 +1250,12 @@ docs = [ { name = "pillow", specifier = "==11.3.0" }, { name = "python-slugify", specifier = "==8.0.4" }, { name = "pyyaml", specifier = ">=5.3.1,<7.0.0" }, - { name = "ruff", specifier = "==0.14.3" }, + { name = "ruff", specifier = "==0.14.14" }, { name = "typer", specifier = "==0.21.1" }, ] docs-tests = [ { name = "httpx", specifier = ">=0.23.0,<1.0.0" }, - { name = "ruff", specifier = "==0.14.3" }, + { name = "ruff", specifier = "==0.14.14" }, ] github-actions = [ { name = "httpx", specifier = ">=0.27.0,<1.0.0" }, @@ -1278,7 +1278,7 @@ tests = [ { name = "pytest", specifier = ">=7.1.3,<9.0.0" }, { name = "pytest-codspeed", specifier = "==4.2.0" }, { name = "pyyaml", specifier = ">=5.3.1,<7.0.0" }, - { name = "ruff", specifier = "==0.14.3" }, + { name = "ruff", specifier = "==0.14.14" }, { name = "sqlmodel", specifier = "==0.0.31" }, { name = "strawberry-graphql", specifier = ">=0.200.0,<1.0.0" }, { name = "types-orjson", specifier = "==3.6.2" }, @@ -4248,28 +4248,28 @@ wheels = [ [[package]] name = "ruff" -version = "0.14.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/75/62/50b7727004dfe361104dfbf898c45a9a2fdfad8c72c04ae62900224d6ecf/ruff-0.14.3.tar.gz", hash = "sha256:4ff876d2ab2b161b6de0aa1f5bd714e8e9b4033dc122ee006925fbacc4f62153", size = 5558687, upload-time = "2025-10-31T00:26:26.878Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ce/8e/0c10ff1ea5d4360ab8bfca4cb2c9d979101a391f3e79d2616c9bf348cd26/ruff-0.14.3-py3-none-linux_armv6l.whl", hash = "sha256:876b21e6c824f519446715c1342b8e60f97f93264012de9d8d10314f8a79c371", size = 12535613, upload-time = "2025-10-31T00:25:44.302Z" }, - { url = "https://files.pythonhosted.org/packages/d3/c8/6724f4634c1daf52409fbf13fefda64aa9c8f81e44727a378b7b73dc590b/ruff-0.14.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b6fd8c79b457bedd2abf2702b9b472147cd860ed7855c73a5247fa55c9117654", size = 12855812, upload-time = "2025-10-31T00:25:47.793Z" }, - { url = "https://files.pythonhosted.org/packages/de/03/db1bce591d55fd5f8a08bb02517fa0b5097b2ccabd4ea1ee29aa72b67d96/ruff-0.14.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:71ff6edca490c308f083156938c0c1a66907151263c4abdcb588602c6e696a14", size = 11944026, upload-time = "2025-10-31T00:25:49.657Z" }, - { url = "https://files.pythonhosted.org/packages/0b/75/4f8dbd48e03272715d12c87dc4fcaaf21b913f0affa5f12a4e9c6f8a0582/ruff-0.14.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:786ee3ce6139772ff9272aaf43296d975c0217ee1b97538a98171bf0d21f87ed", size = 12356818, upload-time = "2025-10-31T00:25:51.949Z" }, - { url = "https://files.pythonhosted.org/packages/ec/9b/506ec5b140c11d44a9a4f284ea7c14ebf6f8b01e6e8917734a3325bff787/ruff-0.14.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cd6291d0061811c52b8e392f946889916757610d45d004e41140d81fb6cd5ddc", size = 12336745, upload-time = "2025-10-31T00:25:54.248Z" }, - { url = "https://files.pythonhosted.org/packages/c7/e1/c560d254048c147f35e7f8131d30bc1f63a008ac61595cf3078a3e93533d/ruff-0.14.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a497ec0c3d2c88561b6d90f9c29f5ae68221ac00d471f306fa21fa4264ce5fcd", size = 13101684, upload-time = "2025-10-31T00:25:56.253Z" }, - { url = "https://files.pythonhosted.org/packages/a5/32/e310133f8af5cd11f8cc30f52522a3ebccc5ea5bff4b492f94faceaca7a8/ruff-0.14.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:e231e1be58fc568950a04fbe6887c8e4b85310e7889727e2b81db205c45059eb", size = 14535000, upload-time = "2025-10-31T00:25:58.397Z" }, - { url = "https://files.pythonhosted.org/packages/a2/a1/7b0470a22158c6d8501eabc5e9b6043c99bede40fa1994cadf6b5c2a61c7/ruff-0.14.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:469e35872a09c0e45fecf48dd960bfbce056b5db2d5e6b50eca329b4f853ae20", size = 14156450, upload-time = "2025-10-31T00:26:00.889Z" }, - { url = "https://files.pythonhosted.org/packages/0a/96/24bfd9d1a7f532b560dcee1a87096332e461354d3882124219bcaff65c09/ruff-0.14.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d6bc90307c469cb9d28b7cfad90aaa600b10d67c6e22026869f585e1e8a2db0", size = 13568414, upload-time = "2025-10-31T00:26:03.291Z" }, - { url = "https://files.pythonhosted.org/packages/a7/e7/138b883f0dfe4ad5b76b58bf4ae675f4d2176ac2b24bdd81b4d966b28c61/ruff-0.14.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2f8a0bbcffcfd895df39c9a4ecd59bb80dca03dc43f7fb63e647ed176b741e", size = 13315293, upload-time = "2025-10-31T00:26:05.708Z" }, - { url = "https://files.pythonhosted.org/packages/33/f4/c09bb898be97b2eb18476b7c950df8815ef14cf956074177e9fbd40b7719/ruff-0.14.3-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:678fdd7c7d2d94851597c23ee6336d25f9930b460b55f8598e011b57c74fd8c5", size = 13539444, upload-time = "2025-10-31T00:26:08.09Z" }, - { url = "https://files.pythonhosted.org/packages/9c/aa/b30a1db25fc6128b1dd6ff0741fa4abf969ded161599d07ca7edd0739cc0/ruff-0.14.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1ec1ac071e7e37e0221d2f2dbaf90897a988c531a8592a6a5959f0603a1ecf5e", size = 12252581, upload-time = "2025-10-31T00:26:10.297Z" }, - { url = "https://files.pythonhosted.org/packages/da/13/21096308f384d796ffe3f2960b17054110a9c3828d223ca540c2b7cc670b/ruff-0.14.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:afcdc4b5335ef440d19e7df9e8ae2ad9f749352190e96d481dc501b753f0733e", size = 12307503, upload-time = "2025-10-31T00:26:12.646Z" }, - { url = "https://files.pythonhosted.org/packages/cb/cc/a350bac23f03b7dbcde3c81b154706e80c6f16b06ff1ce28ed07dc7b07b0/ruff-0.14.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:7bfc42f81862749a7136267a343990f865e71fe2f99cf8d2958f684d23ce3dfa", size = 12675457, upload-time = "2025-10-31T00:26:15.044Z" }, - { url = "https://files.pythonhosted.org/packages/cb/76/46346029fa2f2078826bc88ef7167e8c198e58fe3126636e52f77488cbba/ruff-0.14.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a65e448cfd7e9c59fae8cf37f9221585d3354febaad9a07f29158af1528e165f", size = 13403980, upload-time = "2025-10-31T00:26:17.81Z" }, - { url = "https://files.pythonhosted.org/packages/9f/a4/35f1ef68c4e7b236d4a5204e3669efdeefaef21f0ff6a456792b3d8be438/ruff-0.14.3-py3-none-win32.whl", hash = "sha256:f3d91857d023ba93e14ed2d462ab62c3428f9bbf2b4fbac50a03ca66d31991f7", size = 12500045, upload-time = "2025-10-31T00:26:20.503Z" }, - { url = "https://files.pythonhosted.org/packages/03/15/51960ae340823c9859fb60c63301d977308735403e2134e17d1d2858c7fb/ruff-0.14.3-py3-none-win_amd64.whl", hash = "sha256:d7b7006ac0756306db212fd37116cce2bd307e1e109375e1c6c106002df0ae5f", size = 13594005, upload-time = "2025-10-31T00:26:22.533Z" }, - { url = "https://files.pythonhosted.org/packages/b7/73/4de6579bac8e979fca0a77e54dec1f1e011a0d268165eb8a9bc0982a6564/ruff-0.14.3-py3-none-win_arm64.whl", hash = "sha256:26eb477ede6d399d898791d01961e16b86f02bc2486d0d1a7a9bb2379d055dc1", size = 12590017, upload-time = "2025-10-31T00:26:24.52Z" }, +version = "0.14.14" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2e/06/f71e3a86b2df0dfa2d2f72195941cd09b44f87711cb7fa5193732cb9a5fc/ruff-0.14.14.tar.gz", hash = "sha256:2d0f819c9a90205f3a867dbbd0be083bee9912e170fd7d9704cc8ae45824896b", size = 4515732, upload-time = "2026-01-22T22:30:17.527Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/89/20a12e97bc6b9f9f68343952da08a8099c57237aef953a56b82711d55edd/ruff-0.14.14-py3-none-linux_armv6l.whl", hash = "sha256:7cfe36b56e8489dee8fbc777c61959f60ec0f1f11817e8f2415f429552846aed", size = 10467650, upload-time = "2026-01-22T22:30:08.578Z" }, + { url = "https://files.pythonhosted.org/packages/a3/b1/c5de3fd2d5a831fcae21beda5e3589c0ba67eec8202e992388e4b17a6040/ruff-0.14.14-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6006a0082336e7920b9573ef8a7f52eec837add1265cc74e04ea8a4368cd704c", size = 10883245, upload-time = "2026-01-22T22:30:04.155Z" }, + { url = "https://files.pythonhosted.org/packages/b8/7c/3c1db59a10e7490f8f6f8559d1db8636cbb13dccebf18686f4e3c9d7c772/ruff-0.14.14-py3-none-macosx_11_0_arm64.whl", hash = "sha256:026c1d25996818f0bf498636686199d9bd0d9d6341c9c2c3b62e2a0198b758de", size = 10231273, upload-time = "2026-01-22T22:30:34.642Z" }, + { url = "https://files.pythonhosted.org/packages/a1/6e/5e0e0d9674be0f8581d1f5e0f0a04761203affce3232c1a1189d0e3b4dad/ruff-0.14.14-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f666445819d31210b71e0a6d1c01e24447a20b85458eea25a25fe8142210ae0e", size = 10585753, upload-time = "2026-01-22T22:30:31.781Z" }, + { url = "https://files.pythonhosted.org/packages/23/09/754ab09f46ff1884d422dc26d59ba18b4e5d355be147721bb2518aa2a014/ruff-0.14.14-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3c0f18b922c6d2ff9a5e6c3ee16259adc513ca775bcf82c67ebab7cbd9da5bc8", size = 10286052, upload-time = "2026-01-22T22:30:24.827Z" }, + { url = "https://files.pythonhosted.org/packages/c8/cc/e71f88dd2a12afb5f50733851729d6b571a7c3a35bfdb16c3035132675a0/ruff-0.14.14-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1629e67489c2dea43e8658c3dba659edbfd87361624b4040d1df04c9740ae906", size = 11043637, upload-time = "2026-01-22T22:30:13.239Z" }, + { url = "https://files.pythonhosted.org/packages/67/b2/397245026352494497dac935d7f00f1468c03a23a0c5db6ad8fc49ca3fb2/ruff-0.14.14-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:27493a2131ea0f899057d49d303e4292b2cae2bb57253c1ed1f256fbcd1da480", size = 12194761, upload-time = "2026-01-22T22:30:22.542Z" }, + { url = "https://files.pythonhosted.org/packages/5b/06/06ef271459f778323112c51b7587ce85230785cd64e91772034ddb88f200/ruff-0.14.14-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:01ff589aab3f5b539e35db38425da31a57521efd1e4ad1ae08fc34dbe30bd7df", size = 12005701, upload-time = "2026-01-22T22:30:20.499Z" }, + { url = "https://files.pythonhosted.org/packages/41/d6/99364514541cf811ccc5ac44362f88df66373e9fec1b9d1c4cc830593fe7/ruff-0.14.14-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1cc12d74eef0f29f51775f5b755913eb523546b88e2d733e1d701fe65144e89b", size = 11282455, upload-time = "2026-01-22T22:29:59.679Z" }, + { url = "https://files.pythonhosted.org/packages/ca/71/37daa46f89475f8582b7762ecd2722492df26421714a33e72ccc9a84d7a5/ruff-0.14.14-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb8481604b7a9e75eff53772496201690ce2687067e038b3cc31aaf16aa0b974", size = 11215882, upload-time = "2026-01-22T22:29:57.032Z" }, + { url = "https://files.pythonhosted.org/packages/2c/10/a31f86169ec91c0705e618443ee74ede0bdd94da0a57b28e72db68b2dbac/ruff-0.14.14-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:14649acb1cf7b5d2d283ebd2f58d56b75836ed8c6f329664fa91cdea19e76e66", size = 11180549, upload-time = "2026-01-22T22:30:27.175Z" }, + { url = "https://files.pythonhosted.org/packages/fd/1e/c723f20536b5163adf79bdd10c5f093414293cdf567eed9bdb7b83940f3f/ruff-0.14.14-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e8058d2145566510790eab4e2fad186002e288dec5e0d343a92fe7b0bc1b3e13", size = 10543416, upload-time = "2026-01-22T22:30:01.964Z" }, + { url = "https://files.pythonhosted.org/packages/3e/34/8a84cea7e42c2d94ba5bde1d7a4fae164d6318f13f933d92da6d7c2041ff/ruff-0.14.14-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:e651e977a79e4c758eb807f0481d673a67ffe53cfa92209781dfa3a996cf8412", size = 10285491, upload-time = "2026-01-22T22:30:29.51Z" }, + { url = "https://files.pythonhosted.org/packages/55/ef/b7c5ea0be82518906c978e365e56a77f8de7678c8bb6651ccfbdc178c29f/ruff-0.14.14-py3-none-musllinux_1_2_i686.whl", hash = "sha256:cc8b22da8d9d6fdd844a68ae937e2a0adf9b16514e9a97cc60355e2d4b219fc3", size = 10733525, upload-time = "2026-01-22T22:30:06.499Z" }, + { url = "https://files.pythonhosted.org/packages/6a/5b/aaf1dfbcc53a2811f6cc0a1759de24e4b03e02ba8762daabd9b6bd8c59e3/ruff-0.14.14-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:16bc890fb4cc9781bb05beb5ab4cd51be9e7cb376bf1dd3580512b24eb3fda2b", size = 11315626, upload-time = "2026-01-22T22:30:36.848Z" }, + { url = "https://files.pythonhosted.org/packages/2c/aa/9f89c719c467dfaf8ad799b9bae0df494513fb21d31a6059cb5870e57e74/ruff-0.14.14-py3-none-win32.whl", hash = "sha256:b530c191970b143375b6a68e6f743800b2b786bbcf03a7965b06c4bf04568167", size = 10502442, upload-time = "2026-01-22T22:30:38.93Z" }, + { url = "https://files.pythonhosted.org/packages/87/44/90fa543014c45560cae1fffc63ea059fb3575ee6e1cb654562197e5d16fb/ruff-0.14.14-py3-none-win_amd64.whl", hash = "sha256:3dde1435e6b6fe5b66506c1dff67a421d0b7f6488d466f651c07f4cab3bf20fd", size = 11630486, upload-time = "2026-01-22T22:30:10.852Z" }, + { url = "https://files.pythonhosted.org/packages/9e/6a/40fee331a52339926a92e17ae748827270b288a35ef4a15c9c8f2ec54715/ruff-0.14.14-py3-none-win_arm64.whl", hash = "sha256:56e6981a98b13a32236a72a8da421d7839221fa308b223b9283312312e5ac76c", size = 10920448, upload-time = "2026-01-22T22:30:15.417Z" }, ] [[package]] From 2247750d74b26bc212300cdaff9d82a15bf71eca Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 2 Feb 2026 16:34:52 +0000 Subject: [PATCH 18/56] =?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 0252730c8..e009de8a0 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -41,6 +41,7 @@ hide: ### Internal +* ⬆ Bump ruff from 0.14.3 to 0.14.14. PR [#14798](https://github.com/fastapi/fastapi/pull/14798) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump pyasn1 from 0.6.1 to 0.6.2. PR [#14804](https://github.com/fastapi/fastapi/pull/14804) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump sqlmodel from 0.0.27 to 0.0.31. PR [#14802](https://github.com/fastapi/fastapi/pull/14802) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump mkdocs-macros-plugin from 1.4.1 to 1.5.0. PR [#14801](https://github.com/fastapi/fastapi/pull/14801) by [@dependabot[bot]](https://github.com/apps/dependabot). From f3f498100f1d0edc344e200b215d42a6e46473fd Mon Sep 17 00:00:00 2001 From: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com> Date: Tue, 3 Feb 2026 21:08:08 +0300 Subject: [PATCH 19/56] =?UTF-8?q?=F0=9F=91=B7=20Run=20mypy=20by=20pre-comm?= =?UTF-8?q?it=20(#14806)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sebastián Ramírez --- .pre-commit-config.yaml | 7 +++++++ fastapi/_compat/v2.py | 8 ++++---- fastapi/dependencies/utils.py | 4 ++-- fastapi/utils.py | 2 +- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d88b70b7b..64b84bfbd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -30,6 +30,13 @@ repos: language: unsupported types: [python] + - id: local-mypy + name: mypy check + entry: uv run mypy fastapi + require_serial: true + language: unsupported + pass_filenames: false + - id: add-permalinks-pages language: unsupported name: add-permalinks-pages diff --git a/fastapi/_compat/v2.py b/fastapi/_compat/v2.py index 25b681453..dae78a32e 100644 --- a/fastapi/_compat/v2.py +++ b/fastapi/_compat/v2.py @@ -477,7 +477,7 @@ def get_model_fields(model: type[BaseModel]) -> list[ModelField]: @lru_cache def get_cached_model_fields(model: type[BaseModel]) -> list[ModelField]: - return get_model_fields(model) # type: ignore[return-value] + return get_model_fields(model) # Duplicate of several schema functions from Pydantic v1 to make them compatible with @@ -500,13 +500,13 @@ def get_model_name_map(unique_models: TypeModelSet) -> dict[TypeModelOrEnum, str def get_compat_model_name_map(fields: list[ModelField]) -> ModelNameMap: - all_flat_models = set() + all_flat_models: TypeModelSet = set() v2_model_fields = [field for field in fields if isinstance(field, ModelField)] v2_flat_models = get_flat_models_from_fields(v2_model_fields, known_models=set()) - all_flat_models = all_flat_models.union(v2_flat_models) # type: ignore[arg-type] + all_flat_models = all_flat_models.union(v2_flat_models) - model_name_map = get_model_name_map(all_flat_models) # type: ignore[arg-type] + model_name_map = get_model_name_map(all_flat_models) return model_name_map diff --git a/fastapi/dependencies/utils.py b/fastapi/dependencies/utils.py index 45e1ff3ed..2afc734ba 100644 --- a/fastapi/dependencies/utils.py +++ b/fastapi/dependencies/utils.py @@ -399,7 +399,7 @@ def analyze_param( if isinstance(fastapi_annotation, FieldInfo): # Copy `field_info` because we mutate `field_info.default` below. field_info = copy_field_info( - field_info=fastapi_annotation, # type: ignore[arg-type] + field_info=fastapi_annotation, annotation=use_annotation, ) assert ( @@ -433,7 +433,7 @@ def analyze_param( "Cannot specify FastAPI annotations in `Annotated` and default value" f" together for {param_name!r}" ) - field_info = value # type: ignore[assignment] + field_info = value if isinstance(field_info, FieldInfo): field_info.annotation = type_annotation diff --git a/fastapi/utils.py b/fastapi/utils.py index 78fdcbb5b..1c3a0881f 100644 --- a/fastapi/utils.py +++ b/fastapi/utils.py @@ -90,7 +90,7 @@ def create_model_field( field_info = field_info or FieldInfo(annotation=type_, default=default, alias=alias) kwargs = {"mode": mode, "name": name, "field_info": field_info} try: - return v2.ModelField(**kwargs) # type: ignore[return-value,arg-type] + return v2.ModelField(**kwargs) # type: ignore[arg-type] except PydanticSchemaGenerationError: raise fastapi.exceptions.FastAPIError( _invalid_args_message.format(type_=type_) From eacbce24c9d299c6a28110d9fc8ac50f53cddb08 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 3 Feb 2026 18:08:36 +0000 Subject: [PATCH 20/56] =?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 e009de8a0..ebf3a348f 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -41,6 +41,7 @@ hide: ### Internal +* 👷 Run mypy by pre-commit. PR [#14806](https://github.com/fastapi/fastapi/pull/14806) by [@YuriiMotov](https://github.com/YuriiMotov). * ⬆ Bump ruff from 0.14.3 to 0.14.14. PR [#14798](https://github.com/fastapi/fastapi/pull/14798) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump pyasn1 from 0.6.1 to 0.6.2. PR [#14804](https://github.com/fastapi/fastapi/pull/14804) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump sqlmodel from 0.0.27 to 0.0.31. PR [#14802](https://github.com/fastapi/fastapi/pull/14802) by [@dependabot[bot]](https://github.com/apps/dependabot). From 7621a3aa4b29713aa2ce0ab9605a008a5a8b9335 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Wed, 4 Feb 2026 03:46:32 -0800 Subject: [PATCH 21/56] =?UTF-8?q?=F0=9F=91=B7=20Run=20tests=20only=20on=20?= =?UTF-8?q?relevant=20code=20changes=20(not=20on=20docs)=20(#14813)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test.yml | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 891f76717..5cbbde61f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,7 +16,35 @@ env: UV_NO_SYNC: true jobs: + changes: + runs-on: ubuntu-latest + # Required permissions + permissions: + pull-requests: read + # Set job outputs to values from filter step + outputs: + src: ${{ steps.filter.outputs.src }} + steps: + - uses: actions/checkout@v6 + # For pull requests it's not necessary to checkout the code but for the main branch it is + - uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + src: + - .github/workflows/test.yml + - docs_src/** + - fastapi/** + - scripts/** + - tests/** + - .python-version + - pyproject.toml + - uv.lock + test: + needs: + - changes + if: needs.changes.outputs.src == 'true' strategy: matrix: os: [ windows-latest, macos-latest ] @@ -91,7 +119,8 @@ jobs: include-hidden-files: true coverage-combine: - needs: [test] + needs: + - test runs-on: ubuntu-latest steps: - name: Dump GitHub context @@ -143,3 +172,4 @@ jobs: uses: re-actors/alls-green@release/v1 with: jobs: ${{ toJSON(needs) }} + allowed-skips: coverage-combine,test From dd780f8caa13e3fa755cfabbec0e603f485cae97 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 4 Feb 2026 11:46:55 +0000 Subject: [PATCH 22/56] =?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 ebf3a348f..85c1128fc 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -41,6 +41,7 @@ hide: ### Internal +* 👷 Run tests only on relevant code changes (not on docs). PR [#14813](https://github.com/fastapi/fastapi/pull/14813) by [@tiangolo](https://github.com/tiangolo). * 👷 Run mypy by pre-commit. PR [#14806](https://github.com/fastapi/fastapi/pull/14806) by [@YuriiMotov](https://github.com/YuriiMotov). * ⬆ Bump ruff from 0.14.3 to 0.14.14. PR [#14798](https://github.com/fastapi/fastapi/pull/14798) by [@dependabot[bot]](https://github.com/apps/dependabot). * ⬆ Bump pyasn1 from 0.6.1 to 0.6.2. PR [#14804](https://github.com/fastapi/fastapi/pull/14804) by [@dependabot[bot]](https://github.com/apps/dependabot). From 261736ab4c3d7a3ec642071ba6f9408ebf9618d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Wed, 4 Feb 2026 03:49:00 -0800 Subject: [PATCH 23/56] =?UTF-8?q?=F0=9F=92=A1=20Update=20comment=20for=20P?= =?UTF-8?q?ydantic=20internals=20(#14814)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fastapi/_compat/shared.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fastapi/_compat/shared.py b/fastapi/_compat/shared.py index 419b58f7f..68b9bbdf1 100644 --- a/fastapi/_compat/shared.py +++ b/fastapi/_compat/shared.py @@ -17,7 +17,7 @@ from pydantic.version import VERSION as PYDANTIC_VERSION from starlette.datastructures import UploadFile from typing_extensions import get_args, get_origin -# Copy from Pydantic v2, compatible with v1 +# Copy from Pydantic: pydantic/_internal/_typing_extra.py if sys.version_info < (3, 10): WithArgsTypes: tuple[Any, ...] = (typing._GenericAlias, types.GenericAlias) # type: ignore[attr-defined] else: @@ -45,7 +45,7 @@ sequence_types = tuple(sequence_annotation_to_type.keys()) Url: type[Any] -# Copy of Pydantic v2, compatible with v1 +# Copy of Pydantic: pydantic/_internal/_utils.py def lenient_issubclass( cls: Any, class_or_tuple: Union[type[Any], tuple[type[Any], ...], None] ) -> bool: From 573c593dd04365f0d1dddde2e167851f6d19cef7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 4 Feb 2026 11:49:22 +0000 Subject: [PATCH 24/56] =?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 85c1128fc..20af681fd 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,10 @@ hide: ## Latest Changes +### Refactors + +* 💡 Update comment for Pydantic internals. PR [#14814](https://github.com/fastapi/fastapi/pull/14814) by [@tiangolo](https://github.com/tiangolo). + ### Docs * 📝 Fix minor typos in release notes. PR [#14780](https://github.com/fastapi/fastapi/pull/14780) by [@whyvineet](https://github.com/whyvineet). From dc3278654f13614d255edca66954326966f6620d Mon Sep 17 00:00:00 2001 From: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com> Date: Wed, 4 Feb 2026 14:54:23 +0300 Subject: [PATCH 25/56] =?UTF-8?q?=F0=9F=93=9D=20Use=20`WSGIMiddleware`=20f?= =?UTF-8?q?rom=20`a2wsgi`=20instead=20of=20deprecated=20`fastapi.middlewar?= =?UTF-8?q?e.wsgi.WSGIMiddleware`=20(#14756)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: github-actions[bot] --- docs/en/docs/advanced/wsgi.md | 20 ++++++++++++++++++-- docs/en/docs/reference/middleware.md | 8 -------- docs_src/wsgi/tutorial001_py39.py | 2 +- fastapi/middleware/wsgi.py | 4 +++- pyproject.toml | 2 +- uv.lock | 16 ++++++++++++++++ 6 files changed, 39 insertions(+), 13 deletions(-) diff --git a/docs/en/docs/advanced/wsgi.md b/docs/en/docs/advanced/wsgi.md index 07147df0a..aa68617cf 100644 --- a/docs/en/docs/advanced/wsgi.md +++ b/docs/en/docs/advanced/wsgi.md @@ -6,13 +6,29 @@ For that, you can use the `WSGIMiddleware` and use it to wrap your WSGI applicat ## Using `WSGIMiddleware` { #using-wsgimiddleware } -You need to import `WSGIMiddleware`. +/// info + +This requires installing `a2wsgi` for example with `pip install a2wsgi`. + +/// + +You need to import `WSGIMiddleware` from `a2wsgi`. Then wrap the WSGI (e.g. Flask) app with the middleware. And then mount that under a path. -{* ../../docs_src/wsgi/tutorial001_py39.py hl[2:3,3] *} +{* ../../docs_src/wsgi/tutorial001_py39.py hl[1,3,23] *} + +/// note + +Previously, it was recommended to use `WSGIMiddleware` from `fastapi.middleware.wsgi`, but it is now deprecated. + +It’s advised to use the `a2wsgi` package instead. The usage remains the same. + +Just ensure that you have the `a2wsgi` package installed and import `WSGIMiddleware` correctly from `a2wsgi`. + +/// ## Check it { #check-it } diff --git a/docs/en/docs/reference/middleware.md b/docs/en/docs/reference/middleware.md index 3c666ccda..48ff85158 100644 --- a/docs/en/docs/reference/middleware.md +++ b/docs/en/docs/reference/middleware.md @@ -35,11 +35,3 @@ It can be imported from `fastapi`: ```python from fastapi.middleware.trustedhost import TrustedHostMiddleware ``` - -::: fastapi.middleware.wsgi.WSGIMiddleware - -It can be imported from `fastapi`: - -```python -from fastapi.middleware.wsgi import WSGIMiddleware -``` diff --git a/docs_src/wsgi/tutorial001_py39.py b/docs_src/wsgi/tutorial001_py39.py index 7f27a85a1..8eeceb829 100644 --- a/docs_src/wsgi/tutorial001_py39.py +++ b/docs_src/wsgi/tutorial001_py39.py @@ -1,5 +1,5 @@ +from a2wsgi import WSGIMiddleware from fastapi import FastAPI -from fastapi.middleware.wsgi import WSGIMiddleware from flask import Flask, request from markupsafe import escape diff --git a/fastapi/middleware/wsgi.py b/fastapi/middleware/wsgi.py index c4c6a797d..69e4dcab9 100644 --- a/fastapi/middleware/wsgi.py +++ b/fastapi/middleware/wsgi.py @@ -1 +1,3 @@ -from starlette.middleware.wsgi import WSGIMiddleware as WSGIMiddleware # noqa +from starlette.middleware.wsgi import ( + WSGIMiddleware as WSGIMiddleware, +) # pragma: no cover # noqa diff --git a/pyproject.toml b/pyproject.toml index dea61c6a1..0f6bf1e4a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -178,6 +178,7 @@ tests = [ "strawberry-graphql>=0.200.0,<1.0.0", "types-orjson==3.6.2", "types-ujson==5.10.0.20240515", + "a2wsgi>=1.9.0,<=2.0.0", ] translations = [ "gitpython==3.1.46", @@ -231,7 +232,6 @@ xfail_strict = true junit_family = "xunit2" filterwarnings = [ "error", - 'ignore:starlette.middleware.wsgi is deprecated and will be removed in a future release\..*:DeprecationWarning:starlette', # see https://trio.readthedocs.io/en/stable/history.html#trio-0-22-0-2022-09-28 "ignore:You seem to already have a custom.*:RuntimeWarning:trio", # TODO: remove after upgrading SQLAlchemy to a version that includes the following changes diff --git a/uv.lock b/uv.lock index 2df0b256b..931a27021 100644 --- a/uv.lock +++ b/uv.lock @@ -7,6 +7,18 @@ resolution-markers = [ "python_full_version < '3.10'", ] +[[package]] +name = "a2wsgi" +version = "1.10.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9a/cb/822c56fbea97e9eee201a2e434a80437f6750ebcb1ed307ee3a0a7505b14/a2wsgi-1.10.10.tar.gz", hash = "sha256:a5bcffb52081ba39df0d5e9a884fc6f819d92e3a42389343ba77cbf809fe1f45", size = 18799, upload-time = "2025-06-18T09:00:10.843Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/d5/349aba3dc421e73cbd4958c0ce0a4f1aa3a738bc0d7de75d2f40ed43a535/a2wsgi-1.10.10-py3-none-any.whl", hash = "sha256:d2b21379479718539dc15fce53b876251a0efe7615352dfe49f6ad1bc507848d", size = 17389, upload-time = "2025-06-18T09:00:09.676Z" }, +] + [[package]] name = "ag-ui-protocol" version = "0.1.10" @@ -1058,6 +1070,7 @@ standard-no-fastapi-cloud-cli = [ [package.dev-dependencies] dev = [ + { name = "a2wsgi" }, { name = "anyio", extra = ["trio"] }, { name = "black" }, { name = "cairosvg" }, @@ -1131,6 +1144,7 @@ github-actions = [ { name = "smokeshow" }, ] tests = [ + { name = "a2wsgi" }, { name = "anyio", extra = ["trio"] }, { name = "coverage", version = "7.10.7", source = { registry = "https://pypi.org/simple" }, extra = ["toml"], marker = "python_full_version < '3.10'" }, { name = "coverage", version = "7.13.1", source = { registry = "https://pypi.org/simple" }, extra = ["toml"], marker = "python_full_version >= '3.10'" }, @@ -1197,6 +1211,7 @@ provides-extras = ["standard", "standard-no-fastapi-cloud-cli", "all"] [package.metadata.requires-dev] dev = [ + { name = "a2wsgi", specifier = ">=1.9.0,<=2.0.0" }, { name = "anyio", extras = ["trio"], specifier = ">=3.2.1,<5.0.0" }, { name = "black", specifier = "==25.1.0" }, { name = "cairosvg", specifier = "==2.8.2" }, @@ -1266,6 +1281,7 @@ github-actions = [ { name = "smokeshow", specifier = ">=0.5.0" }, ] tests = [ + { name = "a2wsgi", specifier = ">=1.9.0,<=2.0.0" }, { name = "anyio", extras = ["trio"], specifier = ">=3.2.1,<5.0.0" }, { name = "coverage", extras = ["toml"], specifier = ">=6.5.0,<8.0" }, { name = "dirty-equals", specifier = "==0.9.0" }, From e3a66494c91c0dc4fc423d812c5bf04795358e03 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 4 Feb 2026 11:54:46 +0000 Subject: [PATCH 26/56] =?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 20af681fd..8fc6e8621 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### Docs +* 📝 Use `WSGIMiddleware` from `a2wsgi` instead of deprecated `fastapi.middleware.wsgi.WSGIMiddleware`. PR [#14756](https://github.com/fastapi/fastapi/pull/14756) by [@YuriiMotov](https://github.com/YuriiMotov). * 📝 Fix minor typos in release notes. PR [#14780](https://github.com/fastapi/fastapi/pull/14780) by [@whyvineet](https://github.com/whyvineet). * 🐛 Fix copy button in custom.js. PR [#14722](https://github.com/fastapi/fastapi/pull/14722) by [@fcharrier](https://github.com/fcharrier). * 📝 Add contribution instructions about LLM generated code and comments and automated tools for PRs. PR [#14706](https://github.com/fastapi/fastapi/pull/14706) by [@tiangolo](https://github.com/tiangolo). From 27b91d4ad606876a06f25ea82c989374d54311fd Mon Sep 17 00:00:00 2001 From: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com> Date: Wed, 4 Feb 2026 15:05:19 +0300 Subject: [PATCH 27/56] =?UTF-8?q?=F0=9F=94=A8=20Update=20translation=20scr?= =?UTF-8?q?ipt=20to=20retry=20if=20LLM-response=20doesn't=20pass=20validat?= =?UTF-8?q?ion=20with=20Translation=20Fixer=20tool=20(#14749)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: github-actions[bot] --- scripts/translate.py | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/scripts/translate.py b/scripts/translate.py index eba4ad6a2..9eda7b390 100644 --- a/scripts/translate.py +++ b/scripts/translate.py @@ -10,6 +10,7 @@ from typing import Annotated import git import typer import yaml +from doc_parsing_utils import check_translation from github import Github from pydantic_ai import Agent from rich import print @@ -119,9 +120,30 @@ def translate_page( ] ) prompt = "\n\n".join(prompt_segments) - print(f"Running agent for {out_path}") - result = agent.run_sync(prompt) - out_content = f"{result.output.strip()}\n" + + MAX_ATTEMPTS = 3 + for attempt_no in range(1, MAX_ATTEMPTS + 1): + print(f"Running agent for {out_path} (attempt {attempt_no}/{MAX_ATTEMPTS})") + result = agent.run_sync(prompt) + out_content = f"{result.output.strip()}\n" + try: + check_translation( + doc_lines=out_content.splitlines(), + en_doc_lines=original_content.splitlines(), + lang_code=language, + auto_fix=False, + path=str(out_path), + ) + break # Exit loop if no errors + except ValueError as e: + print( + f"Translation check failed on attempt {attempt_no}/{MAX_ATTEMPTS}: {e}" + ) + continue # Retry if not reached max attempts + else: # Max retry attempts reached + print(f"Translation failed for {out_path} after {MAX_ATTEMPTS} attempts") + raise typer.Exit(code=1) + print(f"Saving translation to {out_path}") out_path.write_text(out_content, encoding="utf-8", newline="\n") From f6ba0141f4736fb78ec80e509634be8d505ae768 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 4 Feb 2026 12:05:41 +0000 Subject: [PATCH 28/56] =?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 8fc6e8621..30704f3e5 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -46,6 +46,7 @@ hide: ### Internal +* 🔨 Update translation script to retry if LLM-response doesn't pass validation with Translation Fixer tool. PR [#14749](https://github.com/fastapi/fastapi/pull/14749) by [@YuriiMotov](https://github.com/YuriiMotov). * 👷 Run tests only on relevant code changes (not on docs). PR [#14813](https://github.com/fastapi/fastapi/pull/14813) by [@tiangolo](https://github.com/tiangolo). * 👷 Run mypy by pre-commit. PR [#14806](https://github.com/fastapi/fastapi/pull/14806) by [@YuriiMotov](https://github.com/YuriiMotov). * ⬆ Bump ruff from 0.14.3 to 0.14.14. PR [#14798](https://github.com/fastapi/fastapi/pull/14798) by [@dependabot[bot]](https://github.com/apps/dependabot). From 741c7345eaecbeedd3ea83f6e7d1048b33ce332b Mon Sep 17 00:00:00 2001 From: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com> Date: Wed, 4 Feb 2026 15:07:26 +0300 Subject: [PATCH 29/56] =?UTF-8?q?=F0=9F=93=9D=20Use=20return=20type=20anno?= =?UTF-8?q?tation=20instead=20of=20`response=5Fmodel`=20when=20possible=20?= =?UTF-8?q?(#14753)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/tutorial/path-operation-configuration.md | 4 ++-- docs_src/app_testing/app_b_an_py310/main.py | 4 ++-- docs_src/app_testing/app_b_an_py39/main.py | 4 ++-- docs_src/app_testing/app_b_py310/main.py | 4 ++-- docs_src/app_testing/app_b_py39/main.py | 4 ++-- docs_src/body_updates/tutorial002_py310.py | 4 ++-- docs_src/body_updates/tutorial002_py39.py | 4 ++-- .../tutorial004_py310.py | 4 ++-- .../path_operation_advanced_configuration/tutorial004_py39.py | 4 ++-- docs_src/path_operation_configuration/tutorial001_py310.py | 4 ++-- docs_src/path_operation_configuration/tutorial001_py39.py | 4 ++-- docs_src/path_operation_configuration/tutorial002_py310.py | 4 ++-- docs_src/path_operation_configuration/tutorial002_py39.py | 4 ++-- docs_src/path_operation_configuration/tutorial003_py310.py | 3 +-- docs_src/path_operation_configuration/tutorial003_py39.py | 3 +-- docs_src/path_operation_configuration/tutorial004_py310.py | 4 ++-- docs_src/path_operation_configuration/tutorial004_py39.py | 4 ++-- docs_src/path_operation_configuration/tutorial005_py310.py | 3 +-- docs_src/path_operation_configuration/tutorial005_py39.py | 3 +-- docs_src/security/tutorial004_an_py310.py | 4 ++-- docs_src/security/tutorial004_an_py39.py | 4 ++-- docs_src/security/tutorial004_py310.py | 4 ++-- docs_src/security/tutorial004_py39.py | 4 ++-- docs_src/security/tutorial005_an_py310.py | 4 ++-- docs_src/security/tutorial005_an_py39.py | 4 ++-- docs_src/security/tutorial005_py310.py | 4 ++-- docs_src/security/tutorial005_py39.py | 4 ++-- 27 files changed, 50 insertions(+), 54 deletions(-) diff --git a/docs/en/docs/tutorial/path-operation-configuration.md b/docs/en/docs/tutorial/path-operation-configuration.md index 59be5ab37..1bb7ee554 100644 --- a/docs/en/docs/tutorial/path-operation-configuration.md +++ b/docs/en/docs/tutorial/path-operation-configuration.md @@ -52,7 +52,7 @@ In these cases, it could make sense to store the tags in an `Enum`. You can add a `summary` and `description`: -{* ../../docs_src/path_operation_configuration/tutorial003_py310.py hl[18:19] *} +{* ../../docs_src/path_operation_configuration/tutorial003_py310.py hl[17:18] *} ## Description from docstring { #description-from-docstring } @@ -70,7 +70,7 @@ It will be used in the interactive docs: You can specify the response description with the parameter `response_description`: -{* ../../docs_src/path_operation_configuration/tutorial005_py310.py hl[19] *} +{* ../../docs_src/path_operation_configuration/tutorial005_py310.py hl[18] *} /// info diff --git a/docs_src/app_testing/app_b_an_py310/main.py b/docs_src/app_testing/app_b_an_py310/main.py index c5952be0b..120289f56 100644 --- a/docs_src/app_testing/app_b_an_py310/main.py +++ b/docs_src/app_testing/app_b_an_py310/main.py @@ -28,8 +28,8 @@ async def read_main(item_id: str, x_token: Annotated[str, Header()]): return fake_db[item_id] -@app.post("/items/", response_model=Item) -async def create_item(item: Item, x_token: Annotated[str, Header()]): +@app.post("/items/") +async def create_item(item: Item, x_token: Annotated[str, Header()]) -> Item: if x_token != fake_secret_token: raise HTTPException(status_code=400, detail="Invalid X-Token header") if item.id in fake_db: diff --git a/docs_src/app_testing/app_b_an_py39/main.py b/docs_src/app_testing/app_b_an_py39/main.py index 142e23a26..801d5f21e 100644 --- a/docs_src/app_testing/app_b_an_py39/main.py +++ b/docs_src/app_testing/app_b_an_py39/main.py @@ -28,8 +28,8 @@ async def read_main(item_id: str, x_token: Annotated[str, Header()]): return fake_db[item_id] -@app.post("/items/", response_model=Item) -async def create_item(item: Item, x_token: Annotated[str, Header()]): +@app.post("/items/") +async def create_item(item: Item, x_token: Annotated[str, Header()]) -> Item: if x_token != fake_secret_token: raise HTTPException(status_code=400, detail="Invalid X-Token header") if item.id in fake_db: diff --git a/docs_src/app_testing/app_b_py310/main.py b/docs_src/app_testing/app_b_py310/main.py index eccedcc7c..6c5c34130 100644 --- a/docs_src/app_testing/app_b_py310/main.py +++ b/docs_src/app_testing/app_b_py310/main.py @@ -26,8 +26,8 @@ async def read_main(item_id: str, x_token: str = Header()): return fake_db[item_id] -@app.post("/items/", response_model=Item) -async def create_item(item: Item, x_token: str = Header()): +@app.post("/items/") +async def create_item(item: Item, x_token: str = Header()) -> Item: if x_token != fake_secret_token: raise HTTPException(status_code=400, detail="Invalid X-Token header") if item.id in fake_db: diff --git a/docs_src/app_testing/app_b_py39/main.py b/docs_src/app_testing/app_b_py39/main.py index 45a103378..89053c432 100644 --- a/docs_src/app_testing/app_b_py39/main.py +++ b/docs_src/app_testing/app_b_py39/main.py @@ -28,8 +28,8 @@ async def read_main(item_id: str, x_token: str = Header()): return fake_db[item_id] -@app.post("/items/", response_model=Item) -async def create_item(item: Item, x_token: str = Header()): +@app.post("/items/") +async def create_item(item: Item, x_token: str = Header()) -> Item: if x_token != fake_secret_token: raise HTTPException(status_code=400, detail="Invalid X-Token header") if item.id in fake_db: diff --git a/docs_src/body_updates/tutorial002_py310.py b/docs_src/body_updates/tutorial002_py310.py index e5db71110..d30e41027 100644 --- a/docs_src/body_updates/tutorial002_py310.py +++ b/docs_src/body_updates/tutorial002_py310.py @@ -25,8 +25,8 @@ async def read_item(item_id: str): return items[item_id] -@app.patch("/items/{item_id}", response_model=Item) -async def update_item(item_id: str, item: Item): +@app.patch("/items/{item_id}") +async def update_item(item_id: str, item: Item) -> Item: stored_item_data = items[item_id] stored_item_model = Item(**stored_item_data) update_data = item.model_dump(exclude_unset=True) diff --git a/docs_src/body_updates/tutorial002_py39.py b/docs_src/body_updates/tutorial002_py39.py index eddd7af71..3714b5a55 100644 --- a/docs_src/body_updates/tutorial002_py39.py +++ b/docs_src/body_updates/tutorial002_py39.py @@ -27,8 +27,8 @@ async def read_item(item_id: str): return items[item_id] -@app.patch("/items/{item_id}", response_model=Item) -async def update_item(item_id: str, item: Item): +@app.patch("/items/{item_id}") +async def update_item(item_id: str, item: Item) -> Item: stored_item_data = items[item_id] stored_item_model = Item(**stored_item_data) update_data = item.model_dump(exclude_unset=True) diff --git a/docs_src/path_operation_advanced_configuration/tutorial004_py310.py b/docs_src/path_operation_advanced_configuration/tutorial004_py310.py index a815a564b..f222b11dc 100644 --- a/docs_src/path_operation_advanced_configuration/tutorial004_py310.py +++ b/docs_src/path_operation_advanced_configuration/tutorial004_py310.py @@ -12,8 +12,8 @@ class Item(BaseModel): tags: set[str] = set() -@app.post("/items/", response_model=Item, summary="Create an item") -async def create_item(item: Item): +@app.post("/items/", summary="Create an item") +async def create_item(item: Item) -> Item: """ Create an item with all the information: diff --git a/docs_src/path_operation_advanced_configuration/tutorial004_py39.py b/docs_src/path_operation_advanced_configuration/tutorial004_py39.py index d5fe6705c..8fabe7cb8 100644 --- a/docs_src/path_operation_advanced_configuration/tutorial004_py39.py +++ b/docs_src/path_operation_advanced_configuration/tutorial004_py39.py @@ -14,8 +14,8 @@ class Item(BaseModel): tags: set[str] = set() -@app.post("/items/", response_model=Item, summary="Create an item") -async def create_item(item: Item): +@app.post("/items/", summary="Create an item") +async def create_item(item: Item) -> Item: """ Create an item with all the information: diff --git a/docs_src/path_operation_configuration/tutorial001_py310.py b/docs_src/path_operation_configuration/tutorial001_py310.py index da078fdf5..2e7488ea4 100644 --- a/docs_src/path_operation_configuration/tutorial001_py310.py +++ b/docs_src/path_operation_configuration/tutorial001_py310.py @@ -12,6 +12,6 @@ class Item(BaseModel): tags: set[str] = set() -@app.post("/items/", response_model=Item, status_code=status.HTTP_201_CREATED) -async def create_item(item: Item): +@app.post("/items/", status_code=status.HTTP_201_CREATED) +async def create_item(item: Item) -> Item: return item diff --git a/docs_src/path_operation_configuration/tutorial001_py39.py b/docs_src/path_operation_configuration/tutorial001_py39.py index a9dcbf389..09b318282 100644 --- a/docs_src/path_operation_configuration/tutorial001_py39.py +++ b/docs_src/path_operation_configuration/tutorial001_py39.py @@ -14,6 +14,6 @@ class Item(BaseModel): tags: set[str] = set() -@app.post("/items/", response_model=Item, status_code=status.HTTP_201_CREATED) -async def create_item(item: Item): +@app.post("/items/", status_code=status.HTTP_201_CREATED) +async def create_item(item: Item) -> Item: return item diff --git a/docs_src/path_operation_configuration/tutorial002_py310.py b/docs_src/path_operation_configuration/tutorial002_py310.py index 9a8af5432..59908ed7c 100644 --- a/docs_src/path_operation_configuration/tutorial002_py310.py +++ b/docs_src/path_operation_configuration/tutorial002_py310.py @@ -12,8 +12,8 @@ class Item(BaseModel): tags: set[str] = set() -@app.post("/items/", response_model=Item, tags=["items"]) -async def create_item(item: Item): +@app.post("/items/", tags=["items"]) +async def create_item(item: Item) -> Item: return item diff --git a/docs_src/path_operation_configuration/tutorial002_py39.py b/docs_src/path_operation_configuration/tutorial002_py39.py index e7ced7de7..fca3b0de9 100644 --- a/docs_src/path_operation_configuration/tutorial002_py39.py +++ b/docs_src/path_operation_configuration/tutorial002_py39.py @@ -14,8 +14,8 @@ class Item(BaseModel): tags: set[str] = set() -@app.post("/items/", response_model=Item, tags=["items"]) -async def create_item(item: Item): +@app.post("/items/", tags=["items"]) +async def create_item(item: Item) -> Item: return item diff --git a/docs_src/path_operation_configuration/tutorial003_py310.py b/docs_src/path_operation_configuration/tutorial003_py310.py index 3d94afe2c..56bd7e36a 100644 --- a/docs_src/path_operation_configuration/tutorial003_py310.py +++ b/docs_src/path_operation_configuration/tutorial003_py310.py @@ -14,9 +14,8 @@ class Item(BaseModel): @app.post( "/items/", - response_model=Item, summary="Create an item", description="Create an item with all the information, name, description, price, tax and a set of unique tags", ) -async def create_item(item: Item): +async def create_item(item: Item) -> Item: return item diff --git a/docs_src/path_operation_configuration/tutorial003_py39.py b/docs_src/path_operation_configuration/tutorial003_py39.py index 607c5707e..a77fb34d8 100644 --- a/docs_src/path_operation_configuration/tutorial003_py39.py +++ b/docs_src/path_operation_configuration/tutorial003_py39.py @@ -16,9 +16,8 @@ class Item(BaseModel): @app.post( "/items/", - response_model=Item, summary="Create an item", description="Create an item with all the information, name, description, price, tax and a set of unique tags", ) -async def create_item(item: Item): +async def create_item(item: Item) -> Item: return item diff --git a/docs_src/path_operation_configuration/tutorial004_py310.py b/docs_src/path_operation_configuration/tutorial004_py310.py index 4cb8bdd43..44404aa08 100644 --- a/docs_src/path_operation_configuration/tutorial004_py310.py +++ b/docs_src/path_operation_configuration/tutorial004_py310.py @@ -12,8 +12,8 @@ class Item(BaseModel): tags: set[str] = set() -@app.post("/items/", response_model=Item, summary="Create an item") -async def create_item(item: Item): +@app.post("/items/", summary="Create an item") +async def create_item(item: Item) -> Item: """ Create an item with all the information: diff --git a/docs_src/path_operation_configuration/tutorial004_py39.py b/docs_src/path_operation_configuration/tutorial004_py39.py index fc25680c5..31dfbff1d 100644 --- a/docs_src/path_operation_configuration/tutorial004_py39.py +++ b/docs_src/path_operation_configuration/tutorial004_py39.py @@ -14,8 +14,8 @@ class Item(BaseModel): tags: set[str] = set() -@app.post("/items/", response_model=Item, summary="Create an item") -async def create_item(item: Item): +@app.post("/items/", summary="Create an item") +async def create_item(item: Item) -> Item: """ Create an item with all the information: diff --git a/docs_src/path_operation_configuration/tutorial005_py310.py b/docs_src/path_operation_configuration/tutorial005_py310.py index b176631d8..a4129d600 100644 --- a/docs_src/path_operation_configuration/tutorial005_py310.py +++ b/docs_src/path_operation_configuration/tutorial005_py310.py @@ -14,11 +14,10 @@ class Item(BaseModel): @app.post( "/items/", - response_model=Item, summary="Create an item", response_description="The created item", ) -async def create_item(item: Item): +async def create_item(item: Item) -> Item: """ Create an item with all the information: diff --git a/docs_src/path_operation_configuration/tutorial005_py39.py b/docs_src/path_operation_configuration/tutorial005_py39.py index ddf29b733..0a53a8f2d 100644 --- a/docs_src/path_operation_configuration/tutorial005_py39.py +++ b/docs_src/path_operation_configuration/tutorial005_py39.py @@ -16,11 +16,10 @@ class Item(BaseModel): @app.post( "/items/", - response_model=Item, summary="Create an item", response_description="The created item", ) -async def create_item(item: Item): +async def create_item(item: Item) -> Item: """ Create an item with all the information: diff --git a/docs_src/security/tutorial004_an_py310.py b/docs_src/security/tutorial004_an_py310.py index 18ea96bc5..368c743bf 100644 --- a/docs_src/security/tutorial004_an_py310.py +++ b/docs_src/security/tutorial004_an_py310.py @@ -133,10 +133,10 @@ async def login_for_access_token( return Token(access_token=access_token, token_type="bearer") -@app.get("/users/me/", response_model=User) +@app.get("/users/me/") async def read_users_me( current_user: Annotated[User, Depends(get_current_active_user)], -): +) -> User: return current_user diff --git a/docs_src/security/tutorial004_an_py39.py b/docs_src/security/tutorial004_an_py39.py index d3fd29e5a..73b3d456d 100644 --- a/docs_src/security/tutorial004_an_py39.py +++ b/docs_src/security/tutorial004_an_py39.py @@ -133,10 +133,10 @@ async def login_for_access_token( return Token(access_token=access_token, token_type="bearer") -@app.get("/users/me/", response_model=User) +@app.get("/users/me/") async def read_users_me( current_user: Annotated[User, Depends(get_current_active_user)], -): +) -> User: return current_user diff --git a/docs_src/security/tutorial004_py310.py b/docs_src/security/tutorial004_py310.py index cd1dcff46..8d0785b40 100644 --- a/docs_src/security/tutorial004_py310.py +++ b/docs_src/security/tutorial004_py310.py @@ -130,8 +130,8 @@ async def login_for_access_token( return Token(access_token=access_token, token_type="bearer") -@app.get("/users/me/", response_model=User) -async def read_users_me(current_user: User = Depends(get_current_active_user)): +@app.get("/users/me/") +async def read_users_me(current_user: User = Depends(get_current_active_user)) -> User: return current_user diff --git a/docs_src/security/tutorial004_py39.py b/docs_src/security/tutorial004_py39.py index 130dc699a..e67403d5d 100644 --- a/docs_src/security/tutorial004_py39.py +++ b/docs_src/security/tutorial004_py39.py @@ -131,8 +131,8 @@ async def login_for_access_token( return Token(access_token=access_token, token_type="bearer") -@app.get("/users/me/", response_model=User) -async def read_users_me(current_user: User = Depends(get_current_active_user)): +@app.get("/users/me/") +async def read_users_me(current_user: User = Depends(get_current_active_user)) -> User: return current_user diff --git a/docs_src/security/tutorial005_an_py310.py b/docs_src/security/tutorial005_an_py310.py index df55951c0..fef0ab71c 100644 --- a/docs_src/security/tutorial005_an_py310.py +++ b/docs_src/security/tutorial005_an_py310.py @@ -160,10 +160,10 @@ async def login_for_access_token( return Token(access_token=access_token, token_type="bearer") -@app.get("/users/me/", response_model=User) +@app.get("/users/me/") async def read_users_me( current_user: Annotated[User, Depends(get_current_active_user)], -): +) -> User: return current_user diff --git a/docs_src/security/tutorial005_an_py39.py b/docs_src/security/tutorial005_an_py39.py index 983c1c22c..1aeba688a 100644 --- a/docs_src/security/tutorial005_an_py39.py +++ b/docs_src/security/tutorial005_an_py39.py @@ -160,10 +160,10 @@ async def login_for_access_token( return Token(access_token=access_token, token_type="bearer") -@app.get("/users/me/", response_model=User) +@app.get("/users/me/") async def read_users_me( current_user: Annotated[User, Depends(get_current_active_user)], -): +) -> User: return current_user diff --git a/docs_src/security/tutorial005_py310.py b/docs_src/security/tutorial005_py310.py index d08e2c59f..412fbf798 100644 --- a/docs_src/security/tutorial005_py310.py +++ b/docs_src/security/tutorial005_py310.py @@ -159,8 +159,8 @@ async def login_for_access_token( return Token(access_token=access_token, token_type="bearer") -@app.get("/users/me/", response_model=User) -async def read_users_me(current_user: User = Depends(get_current_active_user)): +@app.get("/users/me/") +async def read_users_me(current_user: User = Depends(get_current_active_user)) -> User: return current_user diff --git a/docs_src/security/tutorial005_py39.py b/docs_src/security/tutorial005_py39.py index 5bde47ef4..32280aa48 100644 --- a/docs_src/security/tutorial005_py39.py +++ b/docs_src/security/tutorial005_py39.py @@ -160,8 +160,8 @@ async def login_for_access_token( return Token(access_token=access_token, token_type="bearer") -@app.get("/users/me/", response_model=User) -async def read_users_me(current_user: User = Depends(get_current_active_user)): +@app.get("/users/me/") +async def read_users_me(current_user: User = Depends(get_current_active_user)) -> User: return current_user From 5083f27e034ee3b1b3dad459bb420596a952e769 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 4 Feb 2026 12:07:48 +0000 Subject: [PATCH 30/56] =?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 30704f3e5..819c58897 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### Docs +* 📝 Use return type annotation instead of `response_model` when possible. PR [#14753](https://github.com/fastapi/fastapi/pull/14753) by [@YuriiMotov](https://github.com/YuriiMotov). * 📝 Use `WSGIMiddleware` from `a2wsgi` instead of deprecated `fastapi.middleware.wsgi.WSGIMiddleware`. PR [#14756](https://github.com/fastapi/fastapi/pull/14756) by [@YuriiMotov](https://github.com/YuriiMotov). * 📝 Fix minor typos in release notes. PR [#14780](https://github.com/fastapi/fastapi/pull/14780) by [@whyvineet](https://github.com/whyvineet). * 🐛 Fix copy button in custom.js. PR [#14722](https://github.com/fastapi/fastapi/pull/14722) by [@fcharrier](https://github.com/fcharrier). From 21b7b0893b43c1ea359a62b0ec74323d533635fb Mon Sep 17 00:00:00 2001 From: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com> Date: Wed, 4 Feb 2026 15:30:47 +0300 Subject: [PATCH 31/56] =?UTF-8?q?=F0=9F=93=9D=20Fix=20dependency=20install?= =?UTF-8?q?ation=20command=20in=20`docs/en/docs/contributing.md`=20(#14757?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/contributing.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/en/docs/contributing.md b/docs/en/docs/contributing.md index a4d896109..1505dfd1e 100644 --- a/docs/en/docs/contributing.md +++ b/docs/en/docs/contributing.md @@ -13,7 +13,7 @@ Create a virtual environment and install the required packages with ```console -$ uv sync +$ uv sync --extra all ---> 100% ``` @@ -32,9 +32,9 @@ That way, you don't have to "install" your local version to be able to test ever /// note | Technical Details -This only happens when you install using `uv sync` instead of running `pip install fastapi` directly. +This only happens when you install using `uv sync --extra all` instead of running `pip install fastapi` directly. -That is because `uv sync` will install the local version of FastAPI in "editable" mode by default. +That is because `uv sync --extra all` will install the local version of FastAPI in "editable" mode by default. /// From 938c5f3500f4b052ecb5bf73c7ef9058607bfd31 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 4 Feb 2026 12:31:13 +0000 Subject: [PATCH 32/56] =?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 819c58897..926a26a30 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### Docs +* 📝 Fix dependency installation command in `docs/en/docs/contributing.md`. PR [#14757](https://github.com/fastapi/fastapi/pull/14757) by [@YuriiMotov](https://github.com/YuriiMotov). * 📝 Use return type annotation instead of `response_model` when possible. PR [#14753](https://github.com/fastapi/fastapi/pull/14753) by [@YuriiMotov](https://github.com/YuriiMotov). * 📝 Use `WSGIMiddleware` from `a2wsgi` instead of deprecated `fastapi.middleware.wsgi.WSGIMiddleware`. PR [#14756](https://github.com/fastapi/fastapi/pull/14756) by [@YuriiMotov](https://github.com/YuriiMotov). * 📝 Fix minor typos in release notes. PR [#14780](https://github.com/fastapi/fastapi/pull/14780) by [@whyvineet](https://github.com/whyvineet). From 4414286f2c2bfad302dd87637641d635e9a45c00 Mon Sep 17 00:00:00 2001 From: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com> Date: Wed, 4 Feb 2026 15:33:07 +0300 Subject: [PATCH 33/56] =?UTF-8?q?=F0=9F=93=9D=20Update=20embedded=20code?= =?UTF-8?q?=20examples=20to=20Python=203.10=20syntax=20(#14758)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 18 ++++++------------ docs/en/docs/deployment/docker.md | 4 +--- docs/en/docs/index.md | 18 ++++++------------ docs/en/docs/tutorial/body-multiple-params.md | 7 ++++--- 4 files changed, 17 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 1057b8694..963de51ed 100644 --- a/README.md +++ b/README.md @@ -164,8 +164,6 @@ $ pip install "fastapi[standard]" Create a file `main.py` with: ```Python -from typing import Union - from fastapi import FastAPI app = FastAPI() @@ -177,7 +175,7 @@ def read_root(): @app.get("/items/{item_id}") -def read_item(item_id: int, q: Union[str, None] = None): +def read_item(item_id: int, q: str | None = None): return {"item_id": item_id, "q": q} ``` @@ -186,9 +184,7 @@ def read_item(item_id: int, q: Union[str, None] = None): If your code uses `async` / `await`, use `async def`: -```Python hl_lines="9 14" -from typing import Union - +```Python hl_lines="7 12" from fastapi import FastAPI app = FastAPI() @@ -200,7 +196,7 @@ async def read_root(): @app.get("/items/{item_id}") -async def read_item(item_id: int, q: Union[str, None] = None): +async def read_item(item_id: int, q: str | None = None): return {"item_id": item_id, "q": q} ``` @@ -291,9 +287,7 @@ Now modify the file `main.py` to receive a body from a `PUT` request. Declare the body using standard Python types, thanks to Pydantic. -```Python hl_lines="4 9-12 25-27" -from typing import Union - +```Python hl_lines="2 7-10 23-25" from fastapi import FastAPI from pydantic import BaseModel @@ -303,7 +297,7 @@ app = FastAPI() class Item(BaseModel): name: str price: float - is_offer: Union[bool, None] = None + is_offer: bool | None = None @app.get("/") @@ -312,7 +306,7 @@ def read_root(): @app.get("/items/{item_id}") -def read_item(item_id: int, q: Union[str, None] = None): +def read_item(item_id: int, q: str | None = None): return {"item_id": item_id, "q": q} diff --git a/docs/en/docs/deployment/docker.md b/docs/en/docs/deployment/docker.md index 6b71f7360..7219f3afc 100644 --- a/docs/en/docs/deployment/docker.md +++ b/docs/en/docs/deployment/docker.md @@ -145,8 +145,6 @@ There are other formats and tools to define and install package dependencies. * Create a `main.py` file with: ```Python -from typing import Union - from fastapi import FastAPI app = FastAPI() @@ -158,7 +156,7 @@ def read_root(): @app.get("/items/{item_id}") -def read_item(item_id: int, q: Union[str, None] = None): +def read_item(item_id: int, q: str | None = None): return {"item_id": item_id, "q": q} ``` diff --git a/docs/en/docs/index.md b/docs/en/docs/index.md index 5eb47c7b3..ff0f4e9d9 100644 --- a/docs/en/docs/index.md +++ b/docs/en/docs/index.md @@ -161,8 +161,6 @@ $ pip install "fastapi[standard]" Create a file `main.py` with: ```Python -from typing import Union - from fastapi import FastAPI app = FastAPI() @@ -174,7 +172,7 @@ def read_root(): @app.get("/items/{item_id}") -def read_item(item_id: int, q: Union[str, None] = None): +def read_item(item_id: int, q: str | None = None): return {"item_id": item_id, "q": q} ``` @@ -183,9 +181,7 @@ def read_item(item_id: int, q: Union[str, None] = None): If your code uses `async` / `await`, use `async def`: -```Python hl_lines="9 14" -from typing import Union - +```Python hl_lines="7 12" from fastapi import FastAPI app = FastAPI() @@ -197,7 +193,7 @@ async def read_root(): @app.get("/items/{item_id}") -async def read_item(item_id: int, q: Union[str, None] = None): +async def read_item(item_id: int, q: str | None = None): return {"item_id": item_id, "q": q} ``` @@ -288,9 +284,7 @@ Now modify the file `main.py` to receive a body from a `PUT` request. Declare the body using standard Python types, thanks to Pydantic. -```Python hl_lines="4 9-12 25-27" -from typing import Union - +```Python hl_lines="2 7-10 23-25" from fastapi import FastAPI from pydantic import BaseModel @@ -300,7 +294,7 @@ app = FastAPI() class Item(BaseModel): name: str price: float - is_offer: Union[bool, None] = None + is_offer: bool | None = None @app.get("/") @@ -309,7 +303,7 @@ def read_root(): @app.get("/items/{item_id}") -def read_item(item_id: int, q: Union[str, None] = None): +def read_item(item_id: int, q: str | None = None): return {"item_id": item_id, "q": q} diff --git a/docs/en/docs/tutorial/body-multiple-params.md b/docs/en/docs/tutorial/body-multiple-params.md index ed23c8149..bb0c58368 100644 --- a/docs/en/docs/tutorial/body-multiple-params.md +++ b/docs/en/docs/tutorial/body-multiple-params.md @@ -103,15 +103,16 @@ Of course, you can also declare additional query parameters whenever you need, a As, by default, singular values are interpreted as query parameters, you don't have to explicitly add a `Query`, you can just do: ```Python -q: Union[str, None] = None +q: str | None = None ``` -Or in Python 3.10 and above: +Or in Python 3.9: ```Python -q: str | None = None +q: Union[str, None] = None ``` + For example: {* ../../docs_src/body_multiple_params/tutorial004_an_py310.py hl[28] *} From c9e512d808de5eb4196aaaf11ceebf0e9500e55b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 4 Feb 2026 12:33:37 +0000 Subject: [PATCH 34/56] =?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 926a26a30..d5bc81668 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### Docs +* 📝 Update embedded code examples to Python 3.10 syntax. PR [#14758](https://github.com/fastapi/fastapi/pull/14758) by [@YuriiMotov](https://github.com/YuriiMotov). * 📝 Fix dependency installation command in `docs/en/docs/contributing.md`. PR [#14757](https://github.com/fastapi/fastapi/pull/14757) by [@YuriiMotov](https://github.com/YuriiMotov). * 📝 Use return type annotation instead of `response_model` when possible. PR [#14753](https://github.com/fastapi/fastapi/pull/14753) by [@YuriiMotov](https://github.com/YuriiMotov). * 📝 Use `WSGIMiddleware` from `a2wsgi` instead of deprecated `fastapi.middleware.wsgi.WSGIMiddleware`. PR [#14756](https://github.com/fastapi/fastapi/pull/14756) by [@YuriiMotov](https://github.com/YuriiMotov). From 3a41403ccda1a727135fec91dea118ad8f2cf50a Mon Sep 17 00:00:00 2001 From: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com> Date: Wed, 4 Feb 2026 15:41:54 +0300 Subject: [PATCH 35/56] =?UTF-8?q?=F0=9F=93=9D=20Add=20links=20to=20related?= =?UTF-8?q?=20sections=20of=20docs=20to=20docstrings=20(#14776)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: github-actions[bot] --- docs/en/docs/reference/request.md | 2 + docs/en/docs/reference/response.md | 2 + docs/en/docs/reference/responses.md | 2 + docs/en/docs/reference/security/index.md | 2 + docs/en/docs/reference/websockets.md | 24 +++--- fastapi/applications.py | 7 +- fastapi/exceptions.py | 10 +++ fastapi/openapi/docs.py | 30 ++++++++ fastapi/param_functions.py | 94 +++++++++++++++++++++++- fastapi/security/oauth2.py | 30 ++++++++ 10 files changed, 190 insertions(+), 13 deletions(-) diff --git a/docs/en/docs/reference/request.md b/docs/en/docs/reference/request.md index f1de21642..7994bf8a8 100644 --- a/docs/en/docs/reference/request.md +++ b/docs/en/docs/reference/request.md @@ -2,6 +2,8 @@ You can declare a parameter in a *path operation function* or dependency to be of type `Request` and then you can access the raw request object directly, without any validation, etc. +Read more about it in the [FastAPI docs about using Request directly](https://fastapi.tiangolo.com/advanced/using-request-directly/) + You can import it directly from `fastapi`: ```python diff --git a/docs/en/docs/reference/response.md b/docs/en/docs/reference/response.md index 00cf2c499..c9085766c 100644 --- a/docs/en/docs/reference/response.md +++ b/docs/en/docs/reference/response.md @@ -4,6 +4,8 @@ You can declare a parameter in a *path operation function* or dependency to be o You can also use it directly to create an instance of it and return it from your *path operations*. +Read more about it in the [FastAPI docs about returning a custom Response](https://fastapi.tiangolo.com/advanced/response-directly/#returning-a-custom-response) + You can import it directly from `fastapi`: ```python diff --git a/docs/en/docs/reference/responses.md b/docs/en/docs/reference/responses.md index 46f014fcc..bd5786129 100644 --- a/docs/en/docs/reference/responses.md +++ b/docs/en/docs/reference/responses.md @@ -56,6 +56,8 @@ There are a couple of custom FastAPI response classes, you can use them to optim ## Starlette Responses +You can read more about all of them in the [FastAPI docs for Custom Response](https://fastapi.tiangolo.com/advanced/custom-response/) and in the [Starlette docs about Responses](https://starlette.dev/responses/). + ::: fastapi.responses.FileResponse options: members: diff --git a/docs/en/docs/reference/security/index.md b/docs/en/docs/reference/security/index.md index 9a5c5e15f..8163aa2df 100644 --- a/docs/en/docs/reference/security/index.md +++ b/docs/en/docs/reference/security/index.md @@ -28,6 +28,8 @@ from fastapi.security import ( ) ``` +Read more about them in the [FastAPI docs about Security](https://fastapi.tiangolo.com/tutorial/security/). + ## API Key Security Schemes ::: fastapi.security.APIKeyCookie diff --git a/docs/en/docs/reference/websockets.md b/docs/en/docs/reference/websockets.md index 4b7244e08..bd9f438be 100644 --- a/docs/en/docs/reference/websockets.md +++ b/docs/en/docs/reference/websockets.md @@ -2,6 +2,8 @@ When defining WebSockets, you normally declare a parameter of type `WebSocket` and with it you can read data from the client and send data to it. +Read more about it in the [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/) + It is provided directly by Starlette, but you can import it from `fastapi`: ```python @@ -44,16 +46,6 @@ When you want to define dependencies that should be compatible with both HTTP an - send_json - close -When a client disconnects, a `WebSocketDisconnect` exception is raised, you can catch it. - -You can import it directly form `fastapi`: - -```python -from fastapi import WebSocketDisconnect -``` - -::: fastapi.WebSocketDisconnect - ## WebSockets - additional classes Additional classes for handling WebSockets. @@ -66,4 +58,16 @@ from fastapi.websockets import WebSocketDisconnect, WebSocketState ::: fastapi.websockets.WebSocketDisconnect +When a client disconnects, a `WebSocketDisconnect` exception is raised, you can catch it. + +You can import it directly form `fastapi`: + +```python +from fastapi import WebSocketDisconnect +``` + +Read more about it in the [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/#handling-disconnections-and-multiple-clients) + ::: fastapi.websockets.WebSocketState + +`WebSocketState` is an enumeration of the possible states of a WebSocket connection. diff --git a/fastapi/applications.py b/fastapi/applications.py index 54175cb3b..340cabfc2 100644 --- a/fastapi/applications.py +++ b/fastapi/applications.py @@ -672,7 +672,7 @@ class FastAPI(Starlette): in the autogenerated OpenAPI using the `root_path`. Read more about it in the - [FastAPI docs for Behind a Proxy](https://fastapi.tiangolo.com/advanced/behind-a-proxy/#disable-automatic-server-from-root_path). + [FastAPI docs for Behind a Proxy](https://fastapi.tiangolo.com/advanced/behind-a-proxy/#disable-automatic-server-from-root-path). **Example** @@ -739,7 +739,7 @@ class FastAPI(Starlette): It will be added to the generated OpenAPI (e.g. visible at `/docs`). Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). + [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#deprecate-a-path-operation). """ ), ] = None, @@ -812,6 +812,9 @@ class FastAPI(Starlette): In this case, there would be two different schemas, one for input and another one for output. + + Read more about it in the + [FastAPI docs about how to separate schemas for input and output](https://fastapi.tiangolo.com/how-to/separate-openapi-schemas) """ ), ] = True, diff --git a/fastapi/exceptions.py b/fastapi/exceptions.py index 1a3abd80c..62b4674de 100644 --- a/fastapi/exceptions.py +++ b/fastapi/exceptions.py @@ -49,6 +49,9 @@ class HTTPException(StarletteHTTPException): Doc( """ HTTP status code to send to the client. + + Read more about it in the + [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/#use-httpexception) """ ), ], @@ -58,6 +61,9 @@ class HTTPException(StarletteHTTPException): """ Any data to be sent to the client in the `detail` key of the JSON response. + + Read more about it in the + [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/#use-httpexception) """ ), ] = None, @@ -66,6 +72,10 @@ class HTTPException(StarletteHTTPException): Doc( """ Any headers to send to the client in the response. + + Read more about it in the + [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/#add-custom-headers) + """ ), ] = None, diff --git a/fastapi/openapi/docs.py b/fastapi/openapi/docs.py index 82380f85d..632cc2c1d 100644 --- a/fastapi/openapi/docs.py +++ b/fastapi/openapi/docs.py @@ -33,6 +33,9 @@ def get_swagger_ui_html( This is normally done automatically by FastAPI using the default URL `/openapi.json`. + + Read more about it in the + [FastAPI docs for Conditional OpenAPI](https://fastapi.tiangolo.com/how-to/conditional-openapi/#conditional-openapi-from-settings-and-env-vars) """ ), ], @@ -41,6 +44,9 @@ def get_swagger_ui_html( Doc( """ The HTML `` content, normally shown in the browser tab. + + Read more about it in the + [FastAPI docs for Custom Docs UI Static Assets](https://fastapi.tiangolo.com/how-to/custom-docs-ui-assets/) """ ), ], @@ -51,6 +57,9 @@ def get_swagger_ui_html( The URL to use to load the Swagger UI JavaScript. It is normally set to a CDN URL. + + Read more about it in the + [FastAPI docs for Custom Docs UI Static Assets](https://fastapi.tiangolo.com/how-to/custom-docs-ui-assets/) """ ), ] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js", @@ -61,6 +70,9 @@ def get_swagger_ui_html( The URL to use to load the Swagger UI CSS. It is normally set to a CDN URL. + + Read more about it in the + [FastAPI docs for Custom Docs UI Static Assets](https://fastapi.tiangolo.com/how-to/custom-docs-ui-assets/) """ ), ] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css", @@ -77,6 +89,9 @@ def get_swagger_ui_html( Doc( """ The OAuth2 redirect URL, it is normally automatically handled by FastAPI. + + Read more about it in the + [FastAPI docs for Custom Docs UI Static Assets](https://fastapi.tiangolo.com/how-to/custom-docs-ui-assets/) """ ), ] = None, @@ -85,6 +100,9 @@ def get_swagger_ui_html( Doc( """ A dictionary with Swagger UI OAuth2 initialization configurations. + + Read more about the available configuration options in the + [Swagger UI docs](https://swagger.io/docs/open-source-tools/swagger-ui/usage/oauth2/). """ ), ] = None, @@ -95,6 +113,9 @@ def get_swagger_ui_html( Configuration parameters for Swagger UI. It defaults to [swagger_ui_default_parameters][fastapi.openapi.docs.swagger_ui_default_parameters]. + + Read more about it in the + [FastAPI docs about how to Configure Swagger UI](https://fastapi.tiangolo.com/how-to/configure-swagger-ui/). """ ), ] = None, @@ -168,6 +189,9 @@ def get_redoc_html( This is normally done automatically by FastAPI using the default URL `/openapi.json`. + + Read more about it in the + [FastAPI docs for Conditional OpenAPI](https://fastapi.tiangolo.com/how-to/conditional-openapi/#conditional-openapi-from-settings-and-env-vars) """ ), ], @@ -176,6 +200,9 @@ def get_redoc_html( Doc( """ The HTML `<title>` content, normally shown in the browser tab. + + Read more about it in the + [FastAPI docs for Custom Docs UI Static Assets](https://fastapi.tiangolo.com/how-to/custom-docs-ui-assets/) """ ), ], @@ -186,6 +213,9 @@ def get_redoc_html( The URL to use to load the ReDoc JavaScript. It is normally set to a CDN URL. + + Read more about it in the + [FastAPI docs for Custom Docs UI Static Assets](https://fastapi.tiangolo.com/how-to/custom-docs-ui-assets/) """ ), ] = "https://cdn.jsdelivr.net/npm/redoc@2/bundles/redoc.standalone.js", diff --git a/fastapi/param_functions.py b/fastapi/param_functions.py index 0834fd741..9bd92be4c 100644 --- a/fastapi/param_functions.py +++ b/fastapi/param_functions.py @@ -79,6 +79,9 @@ def Path( # noqa: N802 Doc( """ Human-readable title. + + Read more about it in the + [FastAPI docs for Path Parameters and Numeric Validations](https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/#declare-metadata) """ ), ] = None, @@ -96,6 +99,9 @@ def Path( # noqa: N802 """ Greater than. If set, value must be greater than this. Only applicable to numbers. + + Read more about it in the + [FastAPI docs about Path parameters numeric validations](https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/#number-validations-greater-than-and-less-than-or-equal) """ ), ] = None, @@ -105,6 +111,9 @@ def Path( # noqa: N802 """ Greater than or equal. If set, value must be greater than or equal to this. Only applicable to numbers. + + Read more about it in the + [FastAPI docs about Path parameters numeric validations](https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/#number-validations-greater-than-and-less-than-or-equal) """ ), ] = None, @@ -113,6 +122,9 @@ def Path( # noqa: N802 Doc( """ Less than. If set, value must be less than this. Only applicable to numbers. + + Read more about it in the + [FastAPI docs about Path parameters numeric validations](https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/#number-validations-greater-than-and-less-than-or-equal) """ ), ] = None, @@ -122,6 +134,9 @@ def Path( # noqa: N802 """ Less than or equal. If set, value must be less than or equal to this. Only applicable to numbers. + + Read more about it in the + [FastAPI docs about Path parameters numeric validations](https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/#number-validations-greater-than-and-less-than-or-equal) """ ), ] = None, @@ -213,6 +228,9 @@ def Path( # noqa: N802 Doc( """ Example values for this field. + + Read more about it in the + [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/) """ ), ] = None, @@ -343,6 +361,9 @@ def Query( # noqa: N802 Doc( """ Default value if the parameter field is not set. + + Read more about it in the + [FastAPI docs about Query parameters](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#alternative-old-query-as-the-default-value) """ ), ] = Undefined, @@ -367,6 +388,9 @@ def Query( # noqa: N802 This will be used to extract the data and for the generated OpenAPI. It is particularly useful when you can't use the name you want because it is a Python reserved keyword or similar. + + Read more about it in the + [FastAPI docs about Query parameters](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#alias-parameters) """ ), ] = None, @@ -402,6 +426,9 @@ def Query( # noqa: N802 Doc( """ Human-readable title. + + Read more about it in the + [FastAPI docs about Query parameters](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#declare-more-metadata) """ ), ] = None, @@ -410,6 +437,9 @@ def Query( # noqa: N802 Doc( """ Human-readable description. + + Read more about it in the + [FastAPI docs about Query parameters](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#declare-more-metadata) """ ), ] = None, @@ -419,6 +449,9 @@ def Query( # noqa: N802 """ Greater than. If set, value must be greater than this. Only applicable to numbers. + + Read more about it in the + [FastAPI docs about Path parameters numeric validations](https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/#number-validations-greater-than-and-less-than-or-equal) """ ), ] = None, @@ -428,6 +461,9 @@ def Query( # noqa: N802 """ Greater than or equal. If set, value must be greater than or equal to this. Only applicable to numbers. + + Read more about it in the + [FastAPI docs about Path parameters numeric validations](https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/#number-validations-greater-than-and-less-than-or-equal) """ ), ] = None, @@ -436,6 +472,9 @@ def Query( # noqa: N802 Doc( """ Less than. If set, value must be less than this. Only applicable to numbers. + + Read more about it in the + [FastAPI docs about Path parameters numeric validations](https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/#number-validations-greater-than-and-less-than-or-equal) """ ), ] = None, @@ -445,6 +484,9 @@ def Query( # noqa: N802 """ Less than or equal. If set, value must be less than or equal to this. Only applicable to numbers. + + Read more about it in the + [FastAPI docs about Path parameters numeric validations](https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/#number-validations-greater-than-and-less-than-or-equal) """ ), ] = None, @@ -453,6 +495,9 @@ def Query( # noqa: N802 Doc( """ Minimum length for strings. + + Read more about it in the + [FastAPI docs about Query parameters](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/) """ ), ] = None, @@ -461,6 +506,9 @@ def Query( # noqa: N802 Doc( """ Maximum length for strings. + + Read more about it in the + [FastAPI docs about Query parameters](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/) """ ), ] = None, @@ -469,6 +517,9 @@ def Query( # noqa: N802 Doc( """ RegEx pattern for strings. + + Read more about it in the + [FastAPI docs about Query parameters](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#add-regular-expressions """ ), ] = None, @@ -536,6 +587,9 @@ def Query( # noqa: N802 Doc( """ Example values for this field. + + Read more about it in the + [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/) """ ), ] = None, @@ -570,6 +624,9 @@ def Query( # noqa: N802 Mark this parameter field as deprecated. It will affect the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs about Query parameters](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#deprecating-parameters) """ ), ] = None, @@ -581,6 +638,9 @@ def Query( # noqa: N802 You probably don't need it, but it's available. This affects the generated OpenAPI (e.g. visible at `/docs`). + + Read more about it in the + [FastAPI docs about Query parameters](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi """ ), ] = True, @@ -849,6 +909,9 @@ def Header( # noqa: N802 Doc( """ Example values for this field. + + Read more about it in the + [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/) """ ), ] = None, @@ -1152,6 +1215,9 @@ def Cookie( # noqa: N802 Doc( """ Example values for this field. + + Read more about it in the + [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/) """ ), ] = None, @@ -1477,6 +1543,9 @@ def Body( # noqa: N802 Doc( """ Example values for this field. + + Read more about it in the + [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/) """ ), ] = None, @@ -1790,6 +1859,9 @@ def Form( # noqa: N802 Doc( """ Example values for this field. + + Read more about it in the + [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/) """ ), ] = None, @@ -2102,6 +2174,9 @@ def File( # noqa: N802 Doc( """ Example values for this field. + + Read more about it in the + [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/) """ ), ] = None, @@ -2215,6 +2290,9 @@ def Depends( # noqa: N802 Don't call it directly, FastAPI will call it for you, just pass the object directly. + + Read more about it in the + [FastAPI docs for Dependencies](https://fastapi.tiangolo.com/tutorial/dependencies/) """ ), ] = None, @@ -2230,6 +2308,9 @@ def Depends( # noqa: N802 Set `use_cache` to `False` to disable this behavior and ensure the dependency is called again (if declared more than once) in the same request. + + Read more about it in the + [FastAPI docs about sub-dependencies](https://fastapi.tiangolo.com/tutorial/dependencies/sub-dependencies/#using-the-same-dependency-multiple-times) """ ), ] = True, @@ -2250,6 +2331,9 @@ def Depends( # noqa: N802 that handles the request (similar to when using `"function"`), but end **after** the response is sent back to the client. So, the dependency function will be executed **around** the **request** and response cycle. + + Read more about it in the + [FastAPI docs for FastAPI Dependencies with yield](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-with-yield/#early-exit-and-scope) """ ), ] = None, @@ -2295,6 +2379,9 @@ def Security( # noqa: N802 Don't call it directly, FastAPI will call it for you, just pass the object directly. + + Read more about it in the + [FastAPI docs for Dependencies](https://fastapi.tiangolo.com/tutorial/dependencies/) """ ), ] = None, @@ -2312,7 +2399,9 @@ def Security( # noqa: N802 These scopes are integrated with OpenAPI (and the API docs at `/docs`). So they are visible in the OpenAPI specification. - ) + + Read more about it in the + [FastAPI docs about OAuth2 scopes](https://fastapi.tiangolo.com/advanced/security/oauth2-scopes/) """ ), ] = None, @@ -2327,6 +2416,9 @@ def Security( # noqa: N802 Set `use_cache` to `False` to disable this behavior and ensure the dependency is called again (if declared more than once) in the same request. + + Read more about it in the + [FastAPI docs about sub-dependencies](https://fastapi.tiangolo.com/tutorial/dependencies/sub-dependencies/#using-the-same-dependency-multiple-times) """ ), ] = True, diff --git a/fastapi/security/oauth2.py b/fastapi/security/oauth2.py index fc49ba190..58ffc5c76 100644 --- a/fastapi/security/oauth2.py +++ b/fastapi/security/oauth2.py @@ -68,6 +68,9 @@ class OAuth2PasswordRequestForm: "password". Nevertheless, this dependency class is permissive and allows not passing it. If you want to enforce it, use instead the `OAuth2PasswordRequestFormStrict` dependency. + + Read more about it in the + [FastAPI docs for Simple OAuth2 with Password and Bearer](https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/). """ ), ] = None, @@ -78,6 +81,9 @@ class OAuth2PasswordRequestForm: """ `username` string. The OAuth2 spec requires the exact field name `username`. + + Read more about it in the + [FastAPI docs for Simple OAuth2 with Password and Bearer](https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/). """ ), ], @@ -88,6 +94,9 @@ class OAuth2PasswordRequestForm: """ `password` string. The OAuth2 spec requires the exact field name `password`. + + Read more about it in the + [FastAPI docs for Simple OAuth2 with Password and Bearer](https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/). """ ), ], @@ -112,6 +121,9 @@ class OAuth2PasswordRequestForm: * `users:read` * `profile` * `openid` + + Read more about it in the + [FastAPI docs for Simple OAuth2 with Password and Bearer](https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/). """ ), ] = "", @@ -222,6 +234,9 @@ class OAuth2PasswordRequestFormStrict(OAuth2PasswordRequestForm): "password". This dependency is strict about it. If you want to be permissive, use instead the `OAuth2PasswordRequestForm` dependency class. + + Read more about it in the + [FastAPI docs for Simple OAuth2 with Password and Bearer](https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/). """ ), ], @@ -232,6 +247,9 @@ class OAuth2PasswordRequestFormStrict(OAuth2PasswordRequestForm): """ `username` string. The OAuth2 spec requires the exact field name `username`. + + Read more about it in the + [FastAPI docs for Simple OAuth2 with Password and Bearer](https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/). """ ), ], @@ -242,6 +260,9 @@ class OAuth2PasswordRequestFormStrict(OAuth2PasswordRequestForm): """ `password` string. The OAuth2 spec requires the exact field name `password`. + + Read more about it in the + [FastAPI docs for Simple OAuth2 with Password and Bearer](https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/). """ ), ], @@ -266,6 +287,9 @@ class OAuth2PasswordRequestFormStrict(OAuth2PasswordRequestForm): * `users:read` * `profile` * `openid` + + Read more about it in the + [FastAPI docs for Simple OAuth2 with Password and Bearer](https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/). """ ), ] = "", @@ -423,6 +447,9 @@ class OAuth2PasswordBearer(OAuth2): """ The URL to obtain the OAuth2 token. This would be the *path operation* that has `OAuth2PasswordRequestForm` as a dependency. + + Read more about it in the + [FastAPI docs for Simple OAuth2 with Password and Bearer](https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/). """ ), ], @@ -442,6 +469,9 @@ class OAuth2PasswordBearer(OAuth2): """ The OAuth2 scopes that would be required by the *path operations* that use this dependency. + + Read more about it in the + [FastAPI docs for Simple OAuth2 with Password and Bearer](https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/). """ ), ] = None, From 6ab68c62b86c5d222659a37cb2abbd4a52136a94 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 12:42:18 +0000 Subject: [PATCH 36/56] =?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 d5bc81668..0c7d44049 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### Docs +* 📝 Add links to related sections of docs to docstrings. PR [#14776](https://github.com/fastapi/fastapi/pull/14776) by [@YuriiMotov](https://github.com/YuriiMotov). * 📝 Update embedded code examples to Python 3.10 syntax. PR [#14758](https://github.com/fastapi/fastapi/pull/14758) by [@YuriiMotov](https://github.com/YuriiMotov). * 📝 Fix dependency installation command in `docs/en/docs/contributing.md`. PR [#14757](https://github.com/fastapi/fastapi/pull/14757) by [@YuriiMotov](https://github.com/YuriiMotov). * 📝 Use return type annotation instead of `response_model` when possible. PR [#14753](https://github.com/fastapi/fastapi/pull/14753) by [@YuriiMotov](https://github.com/YuriiMotov). From 08dad5c69fbeac83616226b4d56b6c79b8683767 Mon Sep 17 00:00:00 2001 From: DJ Melisso <DJMcoder@users.noreply.github.com> Date: Wed, 4 Feb 2026 05:23:08 -0800 Subject: [PATCH 37/56] =?UTF-8?q?=F0=9F=90=9B=20Fix=20OpenAPI=20duplicatio?= =?UTF-8?q?n=20of=20`anyOf`=20refs=20for=20app-level=20responses=20with=20?= =?UTF-8?q?specified=20`content`=20and=20`model`=20as=20`Union`=20(#14463)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com> --- fastapi/openapi/utils.py | 3 +- ...itional_responses_union_duplicate_anyof.py | 123 ++++++++++++++++++ 2 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 tests/test_additional_responses_union_duplicate_anyof.py diff --git a/fastapi/openapi/utils.py b/fastapi/openapi/utils.py index 75ff26102..d56027b50 100644 --- a/fastapi/openapi/utils.py +++ b/fastapi/openapi/utils.py @@ -1,3 +1,4 @@ +import copy import http.client import inspect import warnings @@ -377,7 +378,7 @@ def get_openapi_path( additional_status_code, additional_response, ) in route.responses.items(): - process_response = additional_response.copy() + process_response = copy.deepcopy(additional_response) process_response.pop("model", None) status_code_key = str(additional_status_code).upper() if status_code_key == "DEFAULT": diff --git a/tests/test_additional_responses_union_duplicate_anyof.py b/tests/test_additional_responses_union_duplicate_anyof.py new file mode 100644 index 000000000..f5d987ca3 --- /dev/null +++ b/tests/test_additional_responses_union_duplicate_anyof.py @@ -0,0 +1,123 @@ +""" +Regression test: Ensure app-level responses with Union models and content/examples +don't accumulate duplicate $ref entries in anyOf arrays. +See https://github.com/fastapi/fastapi/pull/14463 +""" + +from typing import Union + +from fastapi import FastAPI +from fastapi.testclient import TestClient +from pydantic import BaseModel + + +class ModelA(BaseModel): + a: str + + +class ModelB(BaseModel): + b: str + + +app = FastAPI( + responses={ + 500: { + "model": Union[ModelA, ModelB], + "content": {"application/json": {"examples": {"Case A": {"value": "a"}}}}, + } + } +) + + +@app.get("/route1") +async def route1(): + pass # pragma: no cover + + +@app.get("/route2") +async def route2(): + pass # pragma: no cover + + +client = TestClient(app) + + +def test_openapi_schema(): + response = client.get("/openapi.json") + assert response.status_code == 200, response.text + assert response.json() == { + "openapi": "3.1.0", + "info": {"title": "FastAPI", "version": "0.1.0"}, + "paths": { + "/route1": { + "get": { + "summary": "Route1", + "operationId": "route1_route1_get", + "responses": { + "200": { + "description": "Successful Response", + "content": {"application/json": {"schema": {}}}, + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "anyOf": [ + {"$ref": "#/components/schemas/ModelA"}, + {"$ref": "#/components/schemas/ModelB"}, + ], + "title": "Response 500 Route1 Route1 Get", + }, + "examples": {"Case A": {"value": "a"}}, + } + }, + }, + }, + } + }, + "/route2": { + "get": { + "summary": "Route2", + "operationId": "route2_route2_get", + "responses": { + "200": { + "description": "Successful Response", + "content": {"application/json": {"schema": {}}}, + }, + "500": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "anyOf": [ + {"$ref": "#/components/schemas/ModelA"}, + {"$ref": "#/components/schemas/ModelB"}, + ], + "title": "Response 500 Route2 Route2 Get", + }, + "examples": {"Case A": {"value": "a"}}, + } + }, + }, + }, + } + }, + }, + "components": { + "schemas": { + "ModelA": { + "properties": {"a": {"type": "string", "title": "A"}}, + "type": "object", + "required": ["a"], + "title": "ModelA", + }, + "ModelB": { + "properties": {"b": {"type": "string", "title": "B"}}, + "type": "object", + "required": ["b"], + "title": "ModelB", + }, + } + }, + } From ca4692a8c6552de17646a4eabed8ea3cafce597b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 13:23:34 +0000 Subject: [PATCH 38/56] =?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 0c7d44049..59cf84c86 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,10 @@ hide: ## Latest Changes +### Fixes + +* 🐛 Fix OpenAPI duplication of `anyOf` refs for app-level responses with specified `content` and `model` as `Union`. PR [#14463](https://github.com/fastapi/fastapi/pull/14463) by [@DJMcoder](https://github.com/DJMcoder). + ### Refactors * 💡 Update comment for Pydantic internals. PR [#14814](https://github.com/fastapi/fastapi/pull/14814) by [@tiangolo](https://github.com/tiangolo). From 41352de24c41f3df540ea410696aa2116ab59394 Mon Sep 17 00:00:00 2001 From: Anton <34218036+retwish@users.noreply.github.com> Date: Wed, 4 Feb 2026 14:24:59 +0100 Subject: [PATCH 39/56] =?UTF-8?q?=F0=9F=9A=B8=20Improve=20error=20message?= =?UTF-8?q?=20for=20invalid=20query=20parameter=20type=20annotations=20(#1?= =?UTF-8?q?4479)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Anton.D <anton.dehtiarenko@chdp-tech.net> Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com> --- fastapi/dependencies/utils.py | 2 +- tests/test_invalid_sequence_param.py | 20 ++++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/fastapi/dependencies/utils.py b/fastapi/dependencies/utils.py index 2afc734ba..b647818c4 100644 --- a/fastapi/dependencies/utils.py +++ b/fastapi/dependencies/utils.py @@ -519,7 +519,7 @@ def analyze_param( # For Pydantic v1 and getattr(field, "shape", 1) == 1 ) - ) + ), f"Query parameter {param_name!r} must be one of the supported types" return ParamDetails(type_annotation=type_annotation, depends=depends, field=field) diff --git a/tests/test_invalid_sequence_param.py b/tests/test_invalid_sequence_param.py index 2b8fd059e..3695344f7 100644 --- a/tests/test_invalid_sequence_param.py +++ b/tests/test_invalid_sequence_param.py @@ -6,7 +6,10 @@ from pydantic import BaseModel def test_invalid_sequence(): - with pytest.raises(AssertionError): + with pytest.raises( + AssertionError, + match="Query parameter 'q' must be one of the supported types", + ): app = FastAPI() class Item(BaseModel): @@ -18,7 +21,10 @@ def test_invalid_sequence(): def test_invalid_tuple(): - with pytest.raises(AssertionError): + with pytest.raises( + AssertionError, + match="Query parameter 'q' must be one of the supported types", + ): app = FastAPI() class Item(BaseModel): @@ -30,7 +36,10 @@ def test_invalid_tuple(): def test_invalid_dict(): - with pytest.raises(AssertionError): + with pytest.raises( + AssertionError, + match="Query parameter 'q' must be one of the supported types", + ): app = FastAPI() class Item(BaseModel): @@ -42,7 +51,10 @@ def test_invalid_dict(): def test_invalid_simple_dict(): - with pytest.raises(AssertionError): + with pytest.raises( + AssertionError, + match="Query parameter 'q' must be one of the supported types", + ): app = FastAPI() class Item(BaseModel): From 9e0f4ca77ae27798764766fb5dfd48fb15812f86 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 13:25:27 +0000 Subject: [PATCH 40/56] =?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 59cf84c86..0f0b9dd0a 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,10 @@ hide: ## Latest Changes +### Features + +* 🚸 Improve error message for invalid query parameter type annotations. PR [#14479](https://github.com/fastapi/fastapi/pull/14479) by [@retwish](https://github.com/retwish). + ### Fixes * 🐛 Fix OpenAPI duplication of `anyOf` refs for app-level responses with specified `content` and `model` as `Union`. PR [#14463](https://github.com/fastapi/fastapi/pull/14463) by [@DJMcoder](https://github.com/DJMcoder). From 61f95c9606ff548d449e9d1e0612d93e2ec3c97f Mon Sep 17 00:00:00 2001 From: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com> Date: Wed, 4 Feb 2026 16:26:02 +0300 Subject: [PATCH 41/56] =?UTF-8?q?=F0=9F=93=9D=20Add=20banner=20to=20transl?= =?UTF-8?q?ated=20pages=20(#14809)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add banner to translated pages * Add link to English version. Use modern syntax for details block * 🎨 Auto format * Move `translation-banner.md` inside `docs` directory * 🎨 Auto format --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> --- docs/en/docs/translation-banner.md | 11 +++++++++++ docs/ru/docs/translation-banner.md | 11 +++++++++++ scripts/mkdocs_hooks.py | 30 +++++++++++++++++++++++++++++- 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 docs/en/docs/translation-banner.md create mode 100644 docs/ru/docs/translation-banner.md diff --git a/docs/en/docs/translation-banner.md b/docs/en/docs/translation-banner.md new file mode 100644 index 000000000..142287074 --- /dev/null +++ b/docs/en/docs/translation-banner.md @@ -0,0 +1,11 @@ +/// details | 🌐 Translation by AI and humans + +This translation was made by AI guided by humans. 🤝 + +It could have mistakes of misunderstanding the original meaning, or looking unnatural, etc. 🤖 + +You can improve this translation by [helping us guide the AI LLM better](https://fastapi.tiangolo.com/contributing/#translations). + +[English version](ENGLISH_VERSION_URL) + +/// diff --git a/docs/ru/docs/translation-banner.md b/docs/ru/docs/translation-banner.md new file mode 100644 index 000000000..78ebd676c --- /dev/null +++ b/docs/ru/docs/translation-banner.md @@ -0,0 +1,11 @@ +/// details | 🌐 Перевод выполнен с помощью ИИ и людей + +Этот перевод был сделан ИИ под руководством людей. 🤝 + +В нем могут быть ошибки из-за неправильного понимания оригинального смысла или неестественности и т. д. 🤖 + +Вы можете улучшить этот перевод, [помогая нам лучше направлять ИИ LLM](https://fastapi.tiangolo.com/ru/contributing/#translations). + +[Английская версия](ENGLISH_VERSION_URL) + +/// diff --git a/scripts/mkdocs_hooks.py b/scripts/mkdocs_hooks.py index 4b781270a..567c0111d 100644 --- a/scripts/mkdocs_hooks.py +++ b/scripts/mkdocs_hooks.py @@ -26,6 +26,17 @@ def get_missing_translation_content(docs_dir: str) -> str: return missing_translation_path.read_text(encoding="utf-8") +@lru_cache +def get_translation_banner_content(docs_dir: str) -> str: + docs_dir_path = Path(docs_dir) + translation_banner_path = docs_dir_path / "translation-banner.md" + if not translation_banner_path.is_file(): + translation_banner_path = ( + docs_dir_path.parent.parent / "en" / "docs" / "translation-banner.md" + ) + return translation_banner_path.read_text(encoding="utf-8") + + @lru_cache def get_mkdocs_material_langs() -> list[str]: material_path = Path(material.__file__).parent @@ -151,4 +162,21 @@ def on_page_markdown( if markdown.startswith("#"): header, _, body = markdown.partition("\n\n") return f"{header}\n\n{missing_translation_content}\n\n{body}" - return markdown + + docs_dir_path = Path(config.docs_dir) + en_docs_dir_path = docs_dir_path.parent.parent / "en/docs" + + if docs_dir_path == en_docs_dir_path: + return markdown + + # For translated pages add translation banner + translation_banner_content = get_translation_banner_content(config.docs_dir) + en_url = "https://fastapi.tiangolo.com/" + page.url.lstrip("/") + translation_banner_content = translation_banner_content.replace( + "ENGLISH_VERSION_URL", en_url + ) + header = "" + body = markdown + if markdown.startswith("#"): + header, _, body = markdown.partition("\n\n") + return f"{header}\n\n{translation_banner_content}\n\n{body}" From a4297066c22071e89f55fcb9f720dec57bd95814 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 13:26:29 +0000 Subject: [PATCH 42/56] =?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 0f0b9dd0a..7658ab970 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -21,6 +21,7 @@ hide: ### Docs +* 📝 Add banner to translated pages. PR [#14809](https://github.com/fastapi/fastapi/pull/14809) by [@YuriiMotov](https://github.com/YuriiMotov). * 📝 Add links to related sections of docs to docstrings. PR [#14776](https://github.com/fastapi/fastapi/pull/14776) by [@YuriiMotov](https://github.com/YuriiMotov). * 📝 Update embedded code examples to Python 3.10 syntax. PR [#14758](https://github.com/fastapi/fastapi/pull/14758) by [@YuriiMotov](https://github.com/YuriiMotov). * 📝 Fix dependency installation command in `docs/en/docs/contributing.md`. PR [#14757](https://github.com/fastapi/fastapi/pull/14757) by [@YuriiMotov](https://github.com/YuriiMotov). From 3ee652dd0c9e5c1bc38b6cadb6a2a036866c0dd3 Mon Sep 17 00:00:00 2001 From: johnson-earls <125391700+johnson-earls@users.noreply.github.com> Date: Wed, 4 Feb 2026 05:29:02 -0800 Subject: [PATCH 43/56] =?UTF-8?q?=F0=9F=93=9D=20Fix=20example=20of=20licen?= =?UTF-8?q?se=20identifier=20in=20documentation=20(#14492)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: svlandeg <svlandeg@github.com> --- docs_src/metadata/tutorial001_1_py39.py | 2 +- tests/test_tutorial/test_metadata/test_tutorial001_1.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs_src/metadata/tutorial001_1_py39.py b/docs_src/metadata/tutorial001_1_py39.py index a8f5b9458..419232d86 100644 --- a/docs_src/metadata/tutorial001_1_py39.py +++ b/docs_src/metadata/tutorial001_1_py39.py @@ -28,7 +28,7 @@ app = FastAPI( }, license_info={ "name": "Apache 2.0", - "identifier": "MIT", + "identifier": "Apache-2.0", }, ) diff --git a/tests/test_tutorial/test_metadata/test_tutorial001_1.py b/tests/test_tutorial/test_metadata/test_tutorial001_1.py index 40878ccfd..10cb35c54 100644 --- a/tests/test_tutorial/test_metadata/test_tutorial001_1.py +++ b/tests/test_tutorial/test_metadata/test_tutorial001_1.py @@ -28,7 +28,7 @@ def test_openapi_schema(): }, "license": { "name": "Apache 2.0", - "identifier": "MIT", + "identifier": "Apache-2.0", }, "version": "0.0.1", }, From b134f406d1ef4c0b2241f7a0402f3fcb9e99dc8c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 13:29:24 +0000 Subject: [PATCH 44/56] =?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 7658ab970..95d0d794b 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -21,6 +21,7 @@ hide: ### Docs +* 📝 Fix example of license identifier in documentation. PR [#14492](https://github.com/fastapi/fastapi/pull/14492) by [@johnson-earls](https://github.com/johnson-earls). * 📝 Add banner to translated pages. PR [#14809](https://github.com/fastapi/fastapi/pull/14809) by [@YuriiMotov](https://github.com/YuriiMotov). * 📝 Add links to related sections of docs to docstrings. PR [#14776](https://github.com/fastapi/fastapi/pull/14776) by [@YuriiMotov](https://github.com/YuriiMotov). * 📝 Update embedded code examples to Python 3.10 syntax. PR [#14758](https://github.com/fastapi/fastapi/pull/14758) by [@YuriiMotov](https://github.com/YuriiMotov). From 9df1f8293d979506cd75280ed4812658323c2c98 Mon Sep 17 00:00:00 2001 From: Tima <126619011+timakaa@users.noreply.github.com> Date: Wed, 4 Feb 2026 16:32:24 +0300 Subject: [PATCH 45/56] =?UTF-8?q?=F0=9F=93=9D=20Fix=20typing=20issue=20in?= =?UTF-8?q?=20`docs=5Fsrc/app=5Ftesting/app=5Fb`=20code=20example=20(#1457?= =?UTF-8?q?3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com> --- docs_src/app_testing/app_b_an_py310/main.py | 2 +- docs_src/app_testing/app_b_an_py39/main.py | 2 +- docs_src/app_testing/app_b_py310/main.py | 2 +- docs_src/app_testing/app_b_py39/main.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs_src/app_testing/app_b_an_py310/main.py b/docs_src/app_testing/app_b_an_py310/main.py index 120289f56..1b77dd137 100644 --- a/docs_src/app_testing/app_b_an_py310/main.py +++ b/docs_src/app_testing/app_b_an_py310/main.py @@ -34,5 +34,5 @@ async def create_item(item: Item, x_token: Annotated[str, Header()]) -> Item: raise HTTPException(status_code=400, detail="Invalid X-Token header") if item.id in fake_db: raise HTTPException(status_code=409, detail="Item already exists") - fake_db[item.id] = item + fake_db[item.id] = item.model_dump() return item diff --git a/docs_src/app_testing/app_b_an_py39/main.py b/docs_src/app_testing/app_b_an_py39/main.py index 801d5f21e..42026a81a 100644 --- a/docs_src/app_testing/app_b_an_py39/main.py +++ b/docs_src/app_testing/app_b_an_py39/main.py @@ -34,5 +34,5 @@ async def create_item(item: Item, x_token: Annotated[str, Header()]) -> Item: raise HTTPException(status_code=400, detail="Invalid X-Token header") if item.id in fake_db: raise HTTPException(status_code=409, detail="Item already exists") - fake_db[item.id] = item + fake_db[item.id] = item.model_dump() return item diff --git a/docs_src/app_testing/app_b_py310/main.py b/docs_src/app_testing/app_b_py310/main.py index 6c5c34130..83f6fa142 100644 --- a/docs_src/app_testing/app_b_py310/main.py +++ b/docs_src/app_testing/app_b_py310/main.py @@ -32,5 +32,5 @@ async def create_item(item: Item, x_token: str = Header()) -> Item: raise HTTPException(status_code=400, detail="Invalid X-Token header") if item.id in fake_db: raise HTTPException(status_code=409, detail="Item already exists") - fake_db[item.id] = item + fake_db[item.id] = item.model_dump() return item diff --git a/docs_src/app_testing/app_b_py39/main.py b/docs_src/app_testing/app_b_py39/main.py index 89053c432..ed38f4721 100644 --- a/docs_src/app_testing/app_b_py39/main.py +++ b/docs_src/app_testing/app_b_py39/main.py @@ -34,5 +34,5 @@ async def create_item(item: Item, x_token: str = Header()) -> Item: raise HTTPException(status_code=400, detail="Invalid X-Token header") if item.id in fake_db: raise HTTPException(status_code=409, detail="Item already exists") - fake_db[item.id] = item + fake_db[item.id] = item.model_dump() return item From a1bb70e5a5a29cea2c3fce50ab3510b341fdaf8c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 13:32:48 +0000 Subject: [PATCH 46/56] =?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 95d0d794b..aa516c0d6 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -21,6 +21,7 @@ hide: ### Docs +* 📝 Fix typing issue in `docs_src/app_testing/app_b` code example. PR [#14573](https://github.com/fastapi/fastapi/pull/14573) by [@timakaa](https://github.com/timakaa). * 📝 Fix example of license identifier in documentation. PR [#14492](https://github.com/fastapi/fastapi/pull/14492) by [@johnson-earls](https://github.com/johnson-earls). * 📝 Add banner to translated pages. PR [#14809](https://github.com/fastapi/fastapi/pull/14809) by [@YuriiMotov](https://github.com/YuriiMotov). * 📝 Add links to related sections of docs to docstrings. PR [#14776](https://github.com/fastapi/fastapi/pull/14776) by [@YuriiMotov](https://github.com/YuriiMotov). From 0748214c43d0793b56a309199f45b9bf78c0da26 Mon Sep 17 00:00:00 2001 From: mvanderlee <918128+mvanderlee@users.noreply.github.com> Date: Wed, 4 Feb 2026 14:34:01 +0100 Subject: [PATCH 47/56] =?UTF-8?q?=F0=9F=8F=B7=EF=B8=8F=20Re-export=20`IncE?= =?UTF-8?q?x`=20type=20from=20Pydantic=20instead=20of=20duplicating=20it?= =?UTF-8?q?=20(#14641)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fastapi/types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fastapi/types.py b/fastapi/types.py index d3e980cb4..1c3a6de74 100644 --- a/fastapi/types.py +++ b/fastapi/types.py @@ -3,9 +3,9 @@ from enum import Enum from typing import Any, Callable, Optional, TypeVar, Union from pydantic import BaseModel +from pydantic.main import IncEx as IncEx DecoratedCallable = TypeVar("DecoratedCallable", bound=Callable[..., Any]) UnionType = getattr(types, "UnionType", Union) ModelNameMap = dict[Union[type[BaseModel], type[Enum]], str] -IncEx = Union[set[int], set[str], dict[int, Any], dict[str, Any]] DependencyCacheKey = tuple[Optional[Callable[..., Any]], tuple[str, ...], str] From 9656e925a9b53dbb288c24f5dd4cea805c02429b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 13:34:29 +0000 Subject: [PATCH 48/56] =?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 aa516c0d6..12a9ac8a1 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -17,6 +17,7 @@ hide: ### Refactors +* 🏷️ Re-export `IncEx` type from Pydantic instead of duplicating it. PR [#14641](https://github.com/fastapi/fastapi/pull/14641) by [@mvanderlee](https://github.com/mvanderlee). * 💡 Update comment for Pydantic internals. PR [#14814](https://github.com/fastapi/fastapi/pull/14814) by [@tiangolo](https://github.com/tiangolo). ### Docs From 741f77d571eeeb2cde4fe11dcfe038c4d925a046 Mon Sep 17 00:00:00 2001 From: Joab <joab0@proton.me> Date: Wed, 4 Feb 2026 10:35:58 -0300 Subject: [PATCH 49/56] =?UTF-8?q?=E2=9C=A8=20Add=20`viewport`=20meta=20tag?= =?UTF-8?q?=20to=20improve=20Swagger=20UI=20on=20mobile=20devices=20(#1477?= =?UTF-8?q?7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fastapi/openapi/docs.py | 1 + 1 file changed, 1 insertion(+) diff --git a/fastapi/openapi/docs.py b/fastapi/openapi/docs.py index 632cc2c1d..bb387c609 100644 --- a/fastapi/openapi/docs.py +++ b/fastapi/openapi/docs.py @@ -139,6 +139,7 @@ def get_swagger_ui_html( <!DOCTYPE html> <html> <head> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link type="text/css" rel="stylesheet" href="{swagger_css_url}"> <link rel="shortcut icon" href="{swagger_favicon_url}"> <title>{title} From 3675e284abfae4f43dd321301ddfa45bcc494056 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 4 Feb 2026 13:36:24 +0000 Subject: [PATCH 50/56] =?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 12a9ac8a1..45e6cf1c2 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -9,6 +9,7 @@ hide: ### Features +* ✨ Add `viewport` meta tag to improve Swagger UI on mobile devices. PR [#14777](https://github.com/fastapi/fastapi/pull/14777) by [@Joab0](https://github.com/Joab0). * 🚸 Improve error message for invalid query parameter type annotations. PR [#14479](https://github.com/fastapi/fastapi/pull/14479) by [@retwish](https://github.com/retwish). ### Fixes From 1d96b3e3f14fa5a226ae817d1095b868796beb60 Mon Sep 17 00:00:00 2001 From: Cecilia Madrid <61908819+WaveTheory1@users.noreply.github.com> Date: Wed, 4 Feb 2026 14:46:46 +0100 Subject: [PATCH 51/56] =?UTF-8?q?=F0=9F=90=9B=20Strip=20whitespaces=20from?= =?UTF-8?q?=20`Authorization`=20header=20credentials=20(#14786)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fastapi/security/utils.py | 2 +- tests/test_security_http_base.py | 6 ++++++ tests/test_security_oauth2_authorization_code_bearer.py | 6 ++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/fastapi/security/utils.py b/fastapi/security/utils.py index 002e68b44..fd349aec7 100644 --- a/fastapi/security/utils.py +++ b/fastapi/security/utils.py @@ -7,4 +7,4 @@ def get_authorization_scheme_param( if not authorization_header_value: return "", "" scheme, _, param = authorization_header_value.partition(" ") - return scheme, param + return scheme, param.strip() diff --git a/tests/test_security_http_base.py b/tests/test_security_http_base.py index 8cf259a75..ac38ee718 100644 --- a/tests/test_security_http_base.py +++ b/tests/test_security_http_base.py @@ -21,6 +21,12 @@ def test_security_http_base(): assert response.json() == {"scheme": "Other", "credentials": "foobar"} +def test_security_http_base_with_whitespaces(): + response = client.get("/users/me", headers={"Authorization": "Other foobar "}) + assert response.status_code == 200, response.text + assert response.json() == {"scheme": "Other", "credentials": "foobar"} + + def test_security_http_base_no_credentials(): response = client.get("/users/me") assert response.status_code == 401, response.text diff --git a/tests/test_security_oauth2_authorization_code_bearer.py b/tests/test_security_oauth2_authorization_code_bearer.py index f2097b149..66f53ab00 100644 --- a/tests/test_security_oauth2_authorization_code_bearer.py +++ b/tests/test_security_oauth2_authorization_code_bearer.py @@ -37,6 +37,12 @@ def test_token(): assert response.json() == {"token": "testtoken"} +def test_token_with_whitespaces(): + response = client.get("/items", headers={"Authorization": "Bearer testtoken "}) + assert response.status_code == 200, response.text + assert response.json() == {"token": "testtoken"} + + def test_openapi_schema(): response = client.get("/openapi.json") assert response.status_code == 200, response.text From c944add5a9680f7b3dea3a5bab4787949671d2c4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 4 Feb 2026 13:47:09 +0000 Subject: [PATCH 52/56] =?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 45e6cf1c2..091a4c0aa 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -14,6 +14,7 @@ hide: ### Fixes +* 🐛 Strip whitespaces from `Authorization` header credentials. PR [#14786](https://github.com/fastapi/fastapi/pull/14786) by [@WaveTheory1](https://github.com/WaveTheory1). * 🐛 Fix OpenAPI duplication of `anyOf` refs for app-level responses with specified `content` and `model` as `Union`. PR [#14463](https://github.com/fastapi/fastapi/pull/14463) by [@DJMcoder](https://github.com/DJMcoder). ### Refactors From 09f5941f0e18db2b28b40d35a5da7a94c23eb9ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Gu=C3=A9rin?= Date: Wed, 4 Feb 2026 14:49:44 +0100 Subject: [PATCH 53/56] =?UTF-8?q?=F0=9F=90=9B=20Fix=20TYPE=5FCHECKING=20an?= =?UTF-8?q?notations=20for=20Python=203.14=20(PEP=20649)=20(#14789)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fastapi/dependencies/utils.py | 7 ++++- ...stringified_annotation_dependency_py314.py | 30 +++++++++++++++++++ .../test_dependencies/test_tutorial008.py | 10 +++++-- tests/utils.py | 4 +-- 4 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 tests/test_stringified_annotation_dependency_py314.py diff --git a/fastapi/dependencies/utils.py b/fastapi/dependencies/utils.py index b647818c4..fc5dfed85 100644 --- a/fastapi/dependencies/utils.py +++ b/fastapi/dependencies/utils.py @@ -204,7 +204,12 @@ def _get_signature(call: Callable[..., Any]) -> inspect.Signature: except NameError: # Handle type annotations with if TYPE_CHECKING, not used by FastAPI # e.g. dependency return types - signature = inspect.signature(call) + if sys.version_info >= (3, 14): + from annotationlib import Format + + signature = inspect.signature(call, annotation_format=Format.FORWARDREF) + else: + signature = inspect.signature(call) else: signature = inspect.signature(call) return signature diff --git a/tests/test_stringified_annotation_dependency_py314.py b/tests/test_stringified_annotation_dependency_py314.py new file mode 100644 index 000000000..da9b429fc --- /dev/null +++ b/tests/test_stringified_annotation_dependency_py314.py @@ -0,0 +1,30 @@ +from typing import TYPE_CHECKING, Annotated + +from fastapi import Depends, FastAPI +from fastapi.testclient import TestClient + +from .utils import needs_py314 + +if TYPE_CHECKING: # pragma: no cover + + class DummyUser: ... + + +@needs_py314 +def test_stringified_annotation(): + # python3.14: Use forward reference without "from __future__ import annotations" + async def get_current_user() -> DummyUser | None: + return None + + app = FastAPI() + + client = TestClient(app) + + @app.get("/") + async def get( + current_user: Annotated[DummyUser | None, Depends(get_current_user)], + ) -> str: + return "hello world" + + response = client.get("/") + assert response.status_code == 200 diff --git a/tests/test_tutorial/test_dependencies/test_tutorial008.py b/tests/test_tutorial/test_dependencies/test_tutorial008.py index 9d7377ebe..5a2d226bf 100644 --- a/tests/test_tutorial/test_dependencies/test_tutorial008.py +++ b/tests/test_tutorial/test_dependencies/test_tutorial008.py @@ -1,4 +1,5 @@ import importlib +import sys from types import ModuleType from typing import Annotated, Any from unittest.mock import Mock, patch @@ -12,8 +13,13 @@ from fastapi.testclient import TestClient name="module", params=[ "tutorial008_py39", - # Fails with `NameError: name 'DepA' is not defined` - pytest.param("tutorial008_an_py39", marks=pytest.mark.xfail), + pytest.param( + "tutorial008_an_py39", + marks=pytest.mark.xfail( + sys.version_info < (3, 14), + reason="Fails with `NameError: name 'DepA' is not defined`", + ), + ), ], ) def get_module(request: pytest.FixtureRequest): diff --git a/tests/utils.py b/tests/utils.py index efa0bfd52..4cbfee79f 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -6,8 +6,8 @@ needs_py39 = pytest.mark.skipif(sys.version_info < (3, 9), reason="requires pyth needs_py310 = pytest.mark.skipif( sys.version_info < (3, 10), reason="requires python3.10+" ) -needs_py_lt_314 = pytest.mark.skipif( - sys.version_info >= (3, 14), reason="requires python3.13-" +needs_py314 = pytest.mark.skipif( + sys.version_info < (3, 14), reason="requires python3.14+" ) From 5d50b7491579d6b9e9a30cdbe24b08f70dcb8d61 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 4 Feb 2026 13:51:56 +0000 Subject: [PATCH 54/56] =?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 091a4c0aa..eff732da1 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -14,6 +14,7 @@ hide: ### Fixes +* 🐛 Fix TYPE_CHECKING annotations for Python 3.14 (PEP 649). PR [#14789](https://github.com/fastapi/fastapi/pull/14789) by [@mgu](https://github.com/mgu). * 🐛 Strip whitespaces from `Authorization` header credentials. PR [#14786](https://github.com/fastapi/fastapi/pull/14786) by [@WaveTheory1](https://github.com/WaveTheory1). * 🐛 Fix OpenAPI duplication of `anyOf` refs for app-level responses with specified `content` and `model` as `Union`. PR [#14463](https://github.com/fastapi/fastapi/pull/14463) by [@DJMcoder](https://github.com/DJMcoder). From 440bfd70a948c187dadb2e89ee7e94933e867a00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Wed, 4 Feb 2026 06:20:36 -0800 Subject: [PATCH 55/56] =?UTF-8?q?=F0=9F=8E=A8=20Tweak=20types=20for=20mypy?= =?UTF-8?q?=20(#14816)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fastapi/encoders.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fastapi/encoders.py b/fastapi/encoders.py index e8610c983..b4661be4f 100644 --- a/fastapi/encoders.py +++ b/fastapi/encoders.py @@ -219,9 +219,9 @@ def jsonable_encoder( if isinstance(obj, encoder_type): return encoder_instance(obj) if include is not None and not isinstance(include, (set, dict)): - include = set(include) + include = set(include) # type: ignore[assignment] if exclude is not None and not isinstance(exclude, (set, dict)): - exclude = set(exclude) + exclude = set(exclude) # type: ignore[assignment] if isinstance(obj, BaseModel): obj_dict = obj.model_dump( mode="json", From 1e5e8b44cb042f774a8637f27bce93b4ceb68f7d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 4 Feb 2026 14:21:00 +0000 Subject: [PATCH 56/56] =?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 eff732da1..8d90983d4 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -20,6 +20,7 @@ hide: ### Refactors +* 🎨 Tweak types for mypy. PR [#14816](https://github.com/fastapi/fastapi/pull/14816) by [@tiangolo](https://github.com/tiangolo). * 🏷️ Re-export `IncEx` type from Pydantic instead of duplicating it. PR [#14641](https://github.com/fastapi/fastapi/pull/14641) by [@mvanderlee](https://github.com/mvanderlee). * 💡 Update comment for Pydantic internals. PR [#14814](https://github.com/fastapi/fastapi/pull/14814) by [@tiangolo](https://github.com/tiangolo).