Compare commits

..

247 Commits

Author SHA1 Message Date
Sebastián Ramírez
7ddcca6b9a 🔥 Remove unused files from source examples 2026-02-12 11:24:06 +01:00
Sebastián Ramírez
af77d9b718 🔥 Remove test for removed source example 2026-02-12 11:07:43 +01:00
Sebastián Ramírez
400ccb04aa Remove tests for removed files 2026-02-12 11:04:43 +01:00
Sebastián Ramírez
fbfc1722e5 📝 Update source examples and docs from Python 3.9 to 3.10 2026-02-12 00:28:41 +01:00
github-actions[bot]
d06ab3f5c7 📝 Update release notes
[skip ci]
2026-02-11 18:41:46 +00:00
Sebastián Ramírez
3da206c06d 🎨 Update internal types for Python 3.10 (#14898) 2026-02-11 18:41:21 +00:00
github-actions[bot]
cc903bd440 📝 Update release notes
[skip ci]
2026-02-11 18:32:39 +00:00
Sebastián Ramírez
ad4e8e0060 Drop support for Python 3.9 (#14897)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-11 19:32:12 +01:00
Sebastián Ramírez
bdd20051c4 🔖 Release version 0.128.8 2026-02-11 16:16:34 +01:00
github-actions[bot]
1ed9bd4923 📝 Update release notes
[skip ci]
2026-02-11 13:37:37 +00:00
Sebastián Ramírez
aac30fd707 🔨 Tweak PDM hook script (#14895) 2026-02-11 13:37:09 +00:00
github-actions[bot]
417f1ee078 📝 Update release notes
[skip ci]
2026-02-11 12:34:12 +00:00
Sebastián Ramírez
ffb8965260 ♻️ Update build setup for fastapi-slim, deprecate it, and make it only depend on fastapi (#14894) 2026-02-11 12:33:49 +00:00
github-actions[bot]
93fa935fb8 📝 Update release notes
[skip ci]
2026-02-10 12:26:38 +00:00
Sanjana S
f0f3e7a113 📝 Fix grammar in docs/en/docs/tutorial/first-steps.md (#14708) 2026-02-10 13:26:10 +01:00
Sebastián Ramírez
8f82c94de0 🔖 Release version 0.128.7 2026-02-10 13:24:38 +01:00
github-actions[bot]
5bb3423205 📝 Update release notes
[skip ci]
2026-02-10 12:15:02 +00:00
Sebastián Ramírez
6ce5e3e961 Tweak comment in test to reference PR (#14885) 2026-02-10 12:14:38 +00:00
github-actions[bot]
65da3dde12 📝 Update release notes
[skip ci]
2026-02-10 11:56:45 +00:00
Motov Yurii
81f82fd955 🔧 Update LLM-prompt for abbr and dfn tags (#14747)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2026-02-10 11:56:20 +00:00
github-actions[bot]
ff721017df 📝 Update release notes
[skip ci]
2026-02-10 11:49:54 +00:00
Motov Yurii
ca76a4eba9 📝 Use dfn tag for definitions instead of abbr in docs (#14744)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2026-02-10 11:48:27 +00:00
github-actions[bot]
1133a4594d 📝 Update release notes
[skip ci]
2026-02-10 11:47:26 +00:00
Valentyn
38f965985e Test order for the submitted byte Files (#14828)
Co-authored-by: Valentyn Druzhynin <v.druzhynin@zakaz.global>
Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2026-02-10 11:46:48 +00:00
github-actions[bot]
3f1cc8f8f5 📝 Update release notes
[skip ci]
2026-02-10 11:37:19 +00:00
Sebastián Ramírez
25270fcee0 ♻️ Simplify reading files in memory, do it sequentially instead of (fake) parallel (#14884) 2026-02-10 12:36:53 +01:00
github-actions[bot]
8bdb0d2242 📝 Update release notes
[skip ci]
2026-02-10 10:59:10 +00:00
Javier Sánchez Castro
df950111fe Show a clear error on attempt to include router into itself (#14258)
Co-authored-by: Javier Sánchez <javier.sanchez.castro@bookline.ai>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com>
2026-02-10 11:58:40 +01:00
github-actions[bot]
363aced75a 📝 Update release notes
[skip ci]
2026-02-10 10:52:51 +00:00
rijenkii
66dc695071 Replace dict by Mapping on HTTPException.headers (#12997)
Co-authored-by: Alejandra <90076947+alejsdev@users.noreply.github.com>
Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com>
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2026-02-10 11:52:24 +01:00
github-actions[bot]
e94028ab60 📝 Update release notes
[skip ci]
2026-02-09 17:39:11 +00:00
Motov Yurii
8fd291465b 🔧 Configure test workflow to run tests with inline-snapshot=review (#14876) 2026-02-09 18:38:48 +01:00
Sebastián Ramírez
fbca586c1d 📝 Update release notes 2026-02-09 18:25:04 +01:00
github-actions[bot]
4e879799dd 📝 Update release notes
[skip ci]
2026-02-09 17:21:32 +00:00
Sebastián Ramírez
0a4033aeee 🔖 Release version 0.128.6 2026-02-09 18:19:22 +01:00
Motov Yurii
ed2512a5ec 🐛 Fix on_startup and on_shutdown parameters of APIRouter (#14873)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-09 17:31:57 +01:00
github-actions[bot]
0c0f6332e2 📝 Update release notes
[skip ci]
2026-02-09 15:36:09 +00:00
Motov Yurii
227cb85a03 Fix parameterized tests with snapshots (#14875) 2026-02-09 16:35:43 +01:00
github-actions[bot]
cd31576d57 📝 Update release notes
[skip ci]
2026-02-08 10:40:08 +00:00
Sebastián Ramírez
376e108580 🌐 Update translations for zh (update-outdated) (#14843)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com>
Co-authored-by: Yurii Motov <yurii.motov.monte@gmail.com>
2026-02-08 11:39:41 +01:00
Sebastián Ramírez
dedf1409fe 🔖 Release version 0.128.5 2026-02-08 11:20:22 +01:00
github-actions[bot]
79d4dfb37f 📝 Update release notes
[skip ci]
2026-02-08 10:19:07 +00:00
Sebastián Ramírez
9f4ecf562c Add inline snapshot tests for OpenAPI before changes from Pydantic v2 (#14864) 2026-02-08 10:18:38 +00:00
github-actions[bot]
c48539f4c6 📝 Update release notes
[skip ci]
2026-02-07 08:34:59 +00:00
Sebastián Ramírez
2e7d3754cd ♻️ Refactor and simplify Pydantic v2 (and v1) compatibility internal utils (#14862) 2026-02-07 08:34:32 +00:00
Sebastián Ramírez
8eac94bd91 🔖 Release version 0.128.4 2026-02-07 09:12:54 +01:00
github-actions[bot]
58cdfc7f4b 📝 Update release notes
[skip ci]
2026-02-07 08:08:31 +00:00
Sebastián Ramírez
d59fbc3494 ♻️ Refactor internals, simplify Pydantic v2/v1 utils, create_model_field, better types for lenient_issubclass (#14860) 2026-02-07 08:08:07 +00:00
github-actions[bot]
cc6ced6345 📝 Update release notes
[skip ci]
2026-02-06 19:04:48 +00:00
Sebastián Ramírez
cf55bade7e ♻️ Simplify internals, remove Pydantic v1 only logic, no longer needed (#14857) 2026-02-06 19:04:24 +00:00
github-actions[bot]
ac8362c447 📝 Update release notes
[skip ci]
2026-02-06 18:01:30 +00:00
Sebastián Ramírez
3c49346238 ♻️ Refactor internals, cleanup unneeded Pydantic v1 specific logic (#14856) 2026-02-06 19:01:05 +01:00
github-actions[bot]
512c3ad88c 📝 Update release notes
[skip ci]
2026-02-06 17:24:56 +00:00
Motov Yurii
cba537ab71 🌐 Update translations for fr (outdated pages) (#14839) 2026-02-06 18:24:25 +01:00
github-actions[bot]
2eb454ab04 📝 Update release notes
[skip ci]
2026-02-06 17:24:15 +00:00
Motov Yurii
0f5987b560 🌐 Update translations for tr (outdated and missing) (#14838) 2026-02-06 18:23:48 +01:00
github-actions[bot]
266a3138b5 📝 Update release notes
[skip ci]
2026-02-06 17:18:53 +00:00
Sebastián Ramírez
5a31b37cc7 ⬆️ Upgrade development dependencies (#14854) 2026-02-06 17:18:30 +00:00
Sebastián Ramírez
36985f5f25 🔖 Release version 0.128.3 2026-02-06 17:44:11 +01:00
github-actions[bot]
661cdfb8a4 📝 Update release notes
[skip ci]
2026-02-06 16:38:15 +00:00
Sebastián Ramírez
f6cc650a12 ⬆️ Upgrade Starlette supported version range to starlette>=0.40.0,<1.0.0 (#14853) 2026-02-06 16:37:37 +00:00
github-actions[bot]
201feedd68 📝 Update release notes
[skip ci]
2026-02-06 15:31:16 +00:00
Sebastián Ramírez
19f13ead4c 👷 Run tests with Starlette from git (#14849) 2026-02-06 16:30:48 +01:00
github-actions[bot]
01e85c03bd 📝 Update release notes
[skip ci]
2026-02-06 15:29:27 +00:00
Sebastián Ramírez
08233d7ffc 🌐 Update translations for ru (update-outdated) (#14834)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-06 16:28:59 +01:00
github-actions[bot]
fe8c33ea64 📝 Update release notes
[skip ci]
2026-02-06 15:18:55 +00:00
Sebastián Ramírez
f9f7992604 ♻️ Re-implement on_event in FastAPI for compatibility with the next Starlette, while keeping backwards compatibility (#14851) 2026-02-06 16:18:30 +01:00
github-actions[bot]
8e50c55fd9 📝 Update release notes
[skip ci]
2026-02-06 13:45:47 +00:00
Sebastián Ramírez
3b8b310eda 👷 Run tests with lower bound uv sync, upgrade fastapi[all] minimum dependencies: ujson >=5.8.0, orjson >=3.9.3 (#14846) 2026-02-06 14:45:18 +01:00
Sebastián Ramírez
79406a4b04 🔖 Release version 0.128.2 2026-02-05 20:46:37 +01:00
github-actions[bot]
de56c96c64 📝 Update release notes
[skip ci]
2026-02-05 19:42:42 +00:00
Sebastián Ramírez
570e592a03 🌐 Enable Traditional Chinese translations (#14842) 2026-02-05 19:42:18 +00:00
github-actions[bot]
110b45d9b2 📝 Update release notes
[skip ci]
2026-02-05 19:28:17 +00:00
Sebastián Ramírez
72325f698f 🌐 Enable French docs translations (#14841) 2026-02-05 19:27:51 +00:00
github-actions[bot]
8bdbd3725f 📝 Update release notes
[skip ci]
2026-02-05 19:26:13 +00:00
Sebastián Ramírez
23ddf09dd1 🔨 Add max pages to translate to configs (#14840) 2026-02-05 19:25:49 +00:00
github-actions[bot]
6646e2b94f 📝 Update release notes
[skip ci]
2026-02-05 18:42:10 +00:00
Kanetsuna Masaya
c5fd75a321 🐛 Fix using Json[list[str]] type (issue #10997) (#14616)
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>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2026-02-05 18:41:43 +00:00
github-actions[bot]
54f8aeeb9a 📝 Update release notes
[skip ci]
2026-02-05 18:34:59 +00:00
Albin Skott
97145588f5 Add support for PEP695 TypeAliasType (#13920)
Co-authored-by: lokidev <torsten.zielke@protonmail.com>
Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Yurii Motov <yurii.motov.monte@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2026-02-05 18:34:34 +00:00
github-actions[bot]
0dd42b746e 📝 Update release notes
[skip ci]
2026-02-05 18:23:44 +00:00
Jonathan Fulton
b49435becd Allow Response type hint as dependency annotation (#14794)
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>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2026-02-05 18:23:16 +00:00
github-actions[bot]
464c359bb0 📝 Update release notes
[skip ci]
2026-02-05 16:11:33 +00:00
Sebastián Ramírez
457cd75c23 🌐 Update translations for fr (translate-page) (#14837)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-05 16:11:07 +00:00
github-actions[bot]
2838dcb4a8 📝 Update release notes
[skip ci]
2026-02-05 16:06:44 +00:00
github-actions[bot]
b82993643e 📝 Update release notes
[skip ci]
2026-02-05 16:06:09 +00:00
Sebastián Ramírez
b892c3126c 🌐 Update translations for de (update-outdated) (#14836)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-05 16:06:07 +00:00
github-actions[bot]
3578270af4 📝 Update release notes
[skip ci]
2026-02-05 16:05:18 +00:00
Sebastián Ramírez
2224b4e63b 🌐 Update translations for pt (update-outdated) (#14833)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-05 16:05:03 +00:00
Sebastián Ramírez
136d5f0a56 🌐 Update translations for ko (update-outdated) (#14835)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-05 16:04:47 +00:00
github-actions[bot]
afb44f0ff8 📝 Update release notes
[skip ci]
2026-02-05 16:03:19 +00:00
Sebastián Ramírez
4fe06cc24a 🌐 Update translations for es (update-outdated) (#14832)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-05 17:02:22 +01:00
github-actions[bot]
cae2659678 📝 Update release notes
[skip ci]
2026-02-05 15:57:15 +00:00
Sebastián Ramírez
da9e101d50 🌐 Update translations for tr (update-outdated) (#14831)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-05 16:56:49 +01:00
github-actions[bot]
8488d31aff 📝 Update release notes
[skip ci]
2026-02-05 15:48:06 +00:00
Sebastián Ramírez
dcfd432c36 📝 Update docs for translations (#14830) 2026-02-05 16:47:42 +01:00
github-actions[bot]
c7682a198a 📝 Update release notes
[skip ci]
2026-02-05 15:44:05 +00:00
Sebastián Ramírez
b5d276bda8 🌐 Update translations for tr (add-missing) (#14790)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-05 16:43:38 +01:00
github-actions[bot]
2c5a844c44 📝 Update release notes
[skip ci]
2026-02-05 15:34:47 +00:00
Sebastián Ramírez
6ff8ff5b57 🌐 Update translations for fr (update-outdated) (#14826)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-05 16:34:19 +01:00
github-actions[bot]
f23ea3bd95 📝 Update release notes
[skip ci]
2026-02-05 15:33:24 +00:00
Sebastián Ramírez
b4ed7e5b06 🌐 Update translations for zh-hant (update-outdated) (#14825)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-05 16:32:56 +01:00
github-actions[bot]
c00cebc5c6 📝 Update release notes
[skip ci]
2026-02-05 15:31:55 +00:00
Sebastián Ramírez
31faba8e41 🌐 Update translations for uk (update-outdated) (#14822)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com>
Co-authored-by: Maksym Zavalniuk <maksym.z@jome.com>
Co-authored-by: Roman Mashevskyi <romanmashevskyi@proton.me>
2026-02-05 16:31:31 +01:00
github-actions[bot]
64d0ee9104 📝 Update release notes
[skip ci]
2026-02-05 12:49:18 +00:00
Rayyan oumlil
2e170b9585 📝 Fix duplicate word in advanced-dependencies.md (#14815) 2026-02-05 13:48:51 +01:00
github-actions[bot]
5ca11c59e3 📝 Update release notes
[skip ci]
2026-02-04 17:36:12 +00:00
Sebastián Ramírez
0e68d36cd5 🔨 Update docs and translations scripts, enable Turkish (#14824) 2026-02-04 17:35:21 +00:00
Sebastián Ramírez
1de0de56c8 🔖 Release version 0.128.1 2026-02-04 18:33:29 +01:00
github-actions[bot]
734c95b05a 📝 Update release notes
[skip ci]
2026-02-04 17:01:08 +00:00
Sebastián Ramírez
84a5bcf82d ⬇️ Downgrade LLM translations model to GPT-5 to reduce mistakes (#14823) 2026-02-04 18:00:40 +01:00
github-actions[bot]
0e064009fb 📝 Update release notes
[skip ci]
2026-02-04 16:48:16 +00:00
Roman Mashevskyi
ad29e44c81 🌐 Improve LLM prompt of uk documentation (#14795) 2026-02-04 17:47:51 +01:00
github-actions[bot]
71ceac20da 📝 Update release notes
[skip ci]
2026-02-04 16:44:48 +00:00
Sebastián Ramírez
b0e99d66e8 🌐 Update translations for ja (update-outdated) (#14588)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Yurii Motov <yurii.motov.monte@gmail.com>
Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com>
Co-authored-by: Maruo.S <raspi-maru2004@outlook.jp>
2026-02-04 17:44:21 +01:00
github-actions[bot]
cec4be00ba 📝 Update release notes
[skip ci]
2026-02-04 14:49:41 +00:00
Sebastián Ramírez
aea61373ae 🐛 Fix translation script commit in place (#14818) 2026-02-04 15:49:18 +01:00
github-actions[bot]
fe5b617aec 📝 Update release notes
[skip ci]
2026-02-04 14:36:09 +00:00
Sebastián Ramírez
ee0c12521f 📝 Update docs for contributing translations, simplify title (#14817) 2026-02-04 15:35:17 +01:00
github-actions[bot]
4a3a71f1c1 📝 Update release notes
[skip ci]
2026-02-04 14:34:39 +00:00
Jonathan Fulton
75c47187f3 🐛 Update ValidationError schema to include input and ctx (#14791)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2026-02-04 15:34:02 +01:00
github-actions[bot]
1e5e8b44cb 📝 Update release notes
[skip ci]
2026-02-04 14:21:00 +00:00
Sebastián Ramírez
440bfd70a9 🎨 Tweak types for mypy (#14816) 2026-02-04 14:20:36 +00:00
github-actions[bot]
5d50b74915 📝 Update release notes
[skip ci]
2026-02-04 13:51:56 +00:00
Mickaël Guérin
09f5941f0e 🐛 Fix TYPE_CHECKING annotations for Python 3.14 (PEP 649) (#14789) 2026-02-04 14:49:44 +01:00
github-actions[bot]
c944add5a9 📝 Update release notes
[skip ci]
2026-02-04 13:47:09 +00:00
Cecilia Madrid
1d96b3e3f1 🐛 Strip whitespaces from Authorization header credentials (#14786) 2026-02-04 14:46:46 +01:00
github-actions[bot]
3675e284ab 📝 Update release notes
[skip ci]
2026-02-04 13:36:24 +00:00
Joab
741f77d571 Add viewport meta tag to improve Swagger UI on mobile devices (#14777) 2026-02-04 14:35:58 +01:00
github-actions[bot]
9656e925a9 📝 Update release notes
[skip ci]
2026-02-04 13:34:29 +00:00
mvanderlee
0748214c43 🏷️ Re-export IncEx type from Pydantic instead of duplicating it (#14641) 2026-02-04 14:34:01 +01:00
github-actions[bot]
a1bb70e5a5 📝 Update release notes
[skip ci]
2026-02-04 13:32:48 +00:00
Tima
9df1f8293d 📝 Fix typing issue in docs_src/app_testing/app_b code example (#14573)
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>
2026-02-04 14:32:24 +01:00
github-actions[bot]
b134f406d1 📝 Update release notes
[skip ci]
2026-02-04 13:29:24 +00:00
johnson-earls
3ee652dd0c 📝 Fix example of license identifier in documentation (#14492)
Co-authored-by: svlandeg <svlandeg@github.com>
2026-02-04 14:29:02 +01:00
github-actions[bot]
a4297066c2 📝 Update release notes
[skip ci]
2026-02-04 13:26:29 +00:00
Motov Yurii
61f95c9606 📝 Add banner to translated pages (#14809)
* 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>
2026-02-04 14:26:02 +01:00
github-actions[bot]
9e0f4ca77a 📝 Update release notes
[skip ci]
2026-02-04 13:25:27 +00:00
Anton
41352de24c 🚸 Improve error message for invalid query parameter type annotations (#14479)
Co-authored-by: Anton.D <anton.dehtiarenko@chdp-tech.net>
Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com>
2026-02-04 14:24:59 +01:00
github-actions[bot]
ca4692a8c6 📝 Update release notes
[skip ci]
2026-02-04 13:23:34 +00:00
DJ Melisso
08dad5c69f 🐛 Fix OpenAPI duplication of anyOf refs for app-level responses with specified content and model as Union (#14463)
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>
2026-02-04 14:23:08 +01:00
github-actions[bot]
6ab68c62b8 📝 Update release notes
[skip ci]
2026-02-04 12:42:18 +00:00
Motov Yurii
3a41403ccd 📝 Add links to related sections of docs to docstrings (#14776)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-04 13:41:54 +01:00
github-actions[bot]
c9e512d808 📝 Update release notes
[skip ci]
2026-02-04 12:33:37 +00:00
Motov Yurii
4414286f2c 📝 Update embedded code examples to Python 3.10 syntax (#14758) 2026-02-04 13:33:07 +01:00
github-actions[bot]
938c5f3500 📝 Update release notes
[skip ci]
2026-02-04 12:31:13 +00:00
Motov Yurii
21b7b0893b 📝 Fix dependency installation command in docs/en/docs/contributing.md (#14757) 2026-02-04 13:30:47 +01:00
github-actions[bot]
5083f27e03 📝 Update release notes
[skip ci]
2026-02-04 12:07:48 +00:00
Motov Yurii
741c7345ea 📝 Use return type annotation instead of response_model when possible (#14753) 2026-02-04 13:07:26 +01:00
github-actions[bot]
f6ba0141f4 📝 Update release notes
[skip ci]
2026-02-04 12:05:41 +00:00
Motov Yurii
27b91d4ad6 🔨 Update translation script to retry if LLM-response doesn't pass validation with Translation Fixer tool (#14749)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-04 13:05:19 +01:00
github-actions[bot]
e3a66494c9 📝 Update release notes
[skip ci]
2026-02-04 11:54:46 +00:00
Motov Yurii
dc3278654f 📝 Use WSGIMiddleware from a2wsgi instead of deprecated fastapi.middleware.wsgi.WSGIMiddleware (#14756)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-04 12:54:23 +01:00
github-actions[bot]
573c593dd0 📝 Update release notes
[skip ci]
2026-02-04 11:49:22 +00:00
Sebastián Ramírez
261736ab4c 💡 Update comment for Pydantic internals (#14814) 2026-02-04 11:49:00 +00:00
github-actions[bot]
dd780f8caa 📝 Update release notes
[skip ci]
2026-02-04 11:46:55 +00:00
Sebastián Ramírez
7621a3aa4b 👷 Run tests only on relevant code changes (not on docs) (#14813) 2026-02-04 11:46:32 +00:00
github-actions[bot]
eacbce24c9 📝 Update release notes
[skip ci]
2026-02-03 18:08:36 +00:00
Motov Yurii
f3f498100f 👷 Run mypy by pre-commit (#14806)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2026-02-03 19:08:08 +01:00
github-actions[bot]
2247750d74 📝 Update release notes
[skip ci]
2026-02-02 16:34:52 +00:00
dependabot[bot]
ec07e62e1c ⬆ Bump ruff from 0.14.3 to 0.14.14 (#14798)
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] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Sofie Van Landeghem <svlandeg@users.noreply.github.com>
2026-02-02 17:34:26 +01:00
github-actions[bot]
82959de14c 📝 Update release notes
[skip ci]
2026-02-02 15:09:37 +00:00
dependabot[bot]
bc9ad6b134 ⬆ Bump pyasn1 from 0.6.1 to 0.6.2 (#14804)
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] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Sofie Van Landeghem <svlandeg@users.noreply.github.com>
2026-02-02 15:09:12 +00:00
github-actions[bot]
608ff552ba 📝 Update release notes
[skip ci]
2026-02-02 15:00:28 +00:00
github-actions[bot]
87b5333e8a 📝 Update release notes
[skip ci]
2026-02-02 15:00:26 +00:00
github-actions[bot]
ecb1444738 📝 Update release notes
[skip ci]
2026-02-02 14:57:46 +00:00
dependabot[bot]
5c3f0307ae ⬆ Bump sqlmodel from 0.0.27 to 0.0.31 (#14802)
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] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Sofie Van Landeghem <svlandeg@users.noreply.github.com>
2026-02-02 15:57:43 +01:00
dependabot[bot]
f2487ce88c ⬆ Bump mkdocs-macros-plugin from 1.4.1 to 1.5.0 (#14801)
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] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Sofie Van Landeghem <svlandeg@users.noreply.github.com>
2026-02-02 15:57:22 +01:00
dependabot[bot]
a0e34c7473 ⬆ Bump gitpython from 3.1.45 to 3.1.46 (#14800)
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] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Sofie Van Landeghem <svlandeg@users.noreply.github.com>
2026-02-02 15:56:33 +01:00
github-actions[bot]
da4083c30f 📝 Update release notes
[skip ci]
2026-02-02 14:55:12 +00:00
dependabot[bot]
b833e53ade ⬆ Bump typer from 0.16.0 to 0.21.1 (#14799)
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] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Sofie Van Landeghem <svlandeg@users.noreply.github.com>
2026-02-02 15:54:49 +01:00
github-actions[bot]
6173733200 📝 Update release notes
[skip ci]
2026-02-02 10:27:24 +00:00
Sebastián Ramírez
20ff394d75 👥 Update FastAPI GitHub topic repositories (#14803)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-02 11:26:58 +01:00
github-actions[bot]
779f7ddc37 📝 Update release notes
[skip ci]
2026-02-02 10:24:48 +00:00
Sebastián Ramírez
3626d764c1 👥 Update FastAPI People - Contributors and Translators (#14796)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-02 11:24:23 +01:00
github-actions[bot]
07f08fc79a 📝 Update release notes
[skip ci]
2026-02-01 09:44:59 +00:00
Motov Yurii
df6530e002 🌐 Update translations for uk (update outdated, found by fixer tool) (#14739) 2026-02-01 10:44:39 +01:00
github-actions[bot]
08924400c2 📝 Update release notes
[skip ci]
2026-01-31 18:32:52 +00:00
Sebastián Ramírez
c9629e0eb2 🌐 Update translations for tr (update-outdated) (#14745)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-31 18:32:27 +00:00
github-actions[bot]
9348a5e2cf 📝 Update release notes
[skip ci]
2026-01-29 08:23:48 +00:00
Vineet Kumar
a3dccaeb14 📝 Fix minor typos in release notes (#14780)
📝 Fix typos in release notes
2026-01-29 09:23:25 +01:00
github-actions[bot]
8c32e91c10 📝 Update release notes
[skip ci]
2026-01-24 21:18:15 +00:00
JUNG SEUNGHOON
7a0589466c 🌐 Update llm-prompt.md for Korean language (#14763)
* docs(ko): refine 'burger' to '햄버거' and update glossary

* Update docs/ko/llm-prompt.md

Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com>

* Add app and command to glossary

Update glossary: add 애플리케이션 (app) and 명령어 (command)

---------

Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com>
2026-01-24 22:17:54 +01:00
github-actions[bot]
442d007e76 📝 Update release notes
[skip ci]
2026-01-24 21:16:33 +00:00
Motov Yurii
eaf07c5d84 🌐 Update translations for ko (update outdated, found by fixer tool) (#14738)
* Update outdated pages found by fixer tool

* Re-translate with updated prompt (fixed translation for `you`)

* Re-translate with `gtpt-5` model

* Re-translate with new preferred translation for `burger`

* Re-translate with new preferred translations for `app` and `command`
2026-01-24 22:16:10 +01:00
github-actions[bot]
597b435ae7 📝 Update release notes
[skip ci]
2026-01-22 16:33:00 +00:00
Sofie Van Landeghem
74cc27fd5a 🔧 Ensure that an edit to uv.lock gets the internal label (#14759)
add uv.lock to files for labeling the PR with 'internal'
2026-01-22 17:32:34 +01:00
github-actions[bot]
f1a39cab12 📝 Update release notes
[skip ci]
2026-01-22 09:27:58 +00:00
Sebastián Ramírez
509afeb475 🌐 Update translations for de (update-outdated) (#14690)
* 🌐 Update translations for de (update-outdated)

* Apply suggestions from code review

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com>
2026-01-22 10:27:31 +01:00
github-actions[bot]
6e47171e9c 📝 Update release notes
[skip ci]
2026-01-22 07:07:28 +00:00
Motov Yurii
b9b75ba5f1 🌐 Update LLM prompt for Russian translations (#14733)
Add some specific translations
2026-01-22 08:07:05 +01:00
github-actions[bot]
e0abd210f6 📝 Update release notes
[skip ci]
2026-01-20 23:03:31 +00:00
Sebastián Ramírez
2eb978b87a 🌐 Update translations for ru (update-outdated) (#14693)
* 🌐 Update translations for ru (update-outdated)

* 🎨 Auto format

* Apply suggestions from code review

* Apply suggestions from code review 2

* Apply suggestions from code review 3

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com>
2026-01-21 00:03:07 +01:00
github-actions[bot]
50a78bf840 📝 Update release notes
[skip ci]
2026-01-20 20:40:39 +00:00
Sebastián Ramírez
2d459e4845 🌐 Update translations for pt (update-outdated) (#14724)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-20 21:40:17 +01:00
github-actions[bot]
7faa7089d6 📝 Update release notes
[skip ci]
2026-01-20 20:37:28 +00:00
hy.lee
0ab68a762f 🌐 Update Korean LLM prompt (#14740) 2026-01-20 21:37:04 +01:00
github-actions[bot]
7443bc7a46 📝 Update release notes
[skip ci]
2026-01-20 20:34:36 +00:00
Kader Miyanyedi
6afb15c518 🌐 Improve LLM prompt for Turkish translations (#14728) 2026-01-20 21:34:03 +01:00
github-actions[bot]
ad6b2901a6 📝 Update release notes
[skip ci]
2026-01-19 20:56:10 +00:00
Sebastián Ramírez
463a3a24d7 🔧 Update sponsors: remove Requestly (#14735) 2026-01-19 20:55:32 +00:00
github-actions[bot]
db5441eba1 📝 Update release notes
[skip ci]
2026-01-19 20:40:38 +00:00
Sebastián Ramírez
536a5bafe7 🔧 Update sponsors, LambdaTest changes to TestMu AI (#14734) 2026-01-19 21:40:17 +01:00
github-actions[bot]
0c7f2b66d7 📝 Update release notes
[skip ci]
2026-01-16 12:27:29 +00:00
Rafael de Oliveira Marques
9fec72687f 🌐 Update portuguese llm-prompt.md (#14702)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Sofie Van Landeghem <svlandeg@users.noreply.github.com>
2026-01-16 13:27:02 +01:00
github-actions[bot]
8fa635c718 📝 Update release notes
[skip ci]
2026-01-16 11:57:32 +00:00
Sebastián Ramírez
fb15bba819 🌐 Update LLM prompt instructions file for French (#14618) 2026-01-16 12:57:08 +01:00
github-actions[bot]
23bcfa094d 📝 Update release notes
[skip ci]
2026-01-16 11:54:26 +00:00
Sebastián Ramírez
f317ede223 🌐 Update translations for ko (add-missing) (#14699)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-16 12:54:01 +01:00
github-actions[bot]
c597d9cb53 📝 Update release notes
[skip ci]
2026-01-16 10:54:08 +00:00
fcharrier
a96dd013a4 🐛 Fix copy button in custom.js (#14722) 2026-01-16 10:53:45 +00:00
github-actions[bot]
a456e92a21 📝 Update release notes
[skip ci]
2026-01-11 22:23:21 +00:00
Sebastián Ramírez
1be80f4885 📝 Add contribution instructions about LLM generated code and comments and automated tools for PRs (#14706) 2026-01-11 23:22:58 +01:00
github-actions[bot]
e63f382b0f 📝 Update release notes
[skip ci]
2026-01-11 21:19:50 +00:00
Sebastián Ramírez
7b864acf37 📝 Update docs for management tasks (#14705) 2026-01-11 21:19:26 +00:00
github-actions[bot]
e9e0419ed0 📝 Update release notes
[skip ci]
2026-01-11 19:19:29 +00:00
Sebastián Ramírez
249a776b70 📝 Update docs about managing translations (#14704) 2026-01-11 19:19:05 +00:00
github-actions[bot]
97aa825422 📝 Update release notes
[skip ci]
2026-01-11 18:18:58 +00:00
Sebastián Ramírez
1054fbd256 📝 Update docs for contributing with translations (#14701) 2026-01-11 18:18:38 +00:00
github-actions[bot]
effe493ae0 📝 Update release notes
[skip ci]
2026-01-11 16:43:35 +00:00
github-actions[bot]
612a2d20bc 📝 Update release notes
[skip ci]
2026-01-11 16:43:25 +00:00
dependabot[bot]
14f3068762 ⬆ Bump actions/cache from 4 to 5 (#14511)
Bumps [actions/cache](https://github.com/actions/cache) from 4 to 5.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-11 17:42:51 +01:00
dependabot[bot]
d05b18ec40 ⬆ Bump actions/upload-artifact from 5 to 6 (#14525)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-11 17:42:37 +01:00
github-actions[bot]
9a76f2fec9 📝 Update release notes
[skip ci]
2026-01-11 16:42:08 +00:00
dependabot[bot]
0383fb3ab9 ⬆ Bump actions/download-artifact from 6 to 7 (#14526)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 6 to 7.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-11 17:41:45 +01:00
github-actions[bot]
50fa3f7c88 📝 Update release notes
[skip ci]
2026-01-11 00:21:31 +00:00
Sebastián Ramírez
5ec2615b1a 👷 Tweak CI input names (#14688) 2026-01-11 01:21:07 +01:00
github-actions[bot]
16e583413c 📝 Update release notes
[skip ci]
2026-01-11 00:16:33 +00:00
github-actions[bot]
1fedd1c73b 📝 Update release notes
[skip ci]
2026-01-11 00:15:31 +00:00
Sebastián Ramírez
cf8dc98aad 🌐 Update translations for ko (update-outdated) (#14589)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Yurii Motov <yurii.motov.monte@gmail.com>
2026-01-11 00:15:26 +00:00
Sebastián Ramírez
6f977366a4 🌐 Update translations for uk (update-outdated) (#14587)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Yurii Motov <yurii.motov.monte@gmail.com>
2026-01-11 01:15:06 +01:00
github-actions[bot]
154ce03ff0 📝 Update release notes
[skip ci]
2026-01-11 00:04:10 +00:00
Sebastián Ramírez
49653aa295 🔨 Refactor translation script to allow committing in place (#14687) 2026-01-11 00:03:50 +00:00
github-actions[bot]
f03a1502a0 📝 Update release notes
[skip ci]
2026-01-10 23:41:44 +00:00
Sebastián Ramírez
a2912ffa26 🌐 Update translations for es (update-outdated) (#14686)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-11 00:41:20 +01:00
github-actions[bot]
8183e748ee 📝 Update release notes
[skip ci]
2026-01-10 23:06:59 +00:00
Sebastián Ramírez
cefd50702a 🐛 Fix translation script path (#14685) 2026-01-10 23:06:37 +00:00
github-actions[bot]
3d1f9268fc 📝 Update release notes
[skip ci]
2026-01-10 22:44:05 +00:00
Sebastián Ramírez
7eac6e3169 Enable tests in CI for scripts (#14684) 2026-01-10 23:43:44 +01:00
github-actions[bot]
21d2c5cea0 📝 Update release notes
[skip ci]
2026-01-10 22:18:13 +00:00
Sebastián Ramírez
c75ae058e4 🔧 Add pre-commit local script to fix language translations (#14683) 2026-01-10 22:17:46 +00:00
github-actions[bot]
961b2e844a 📝 Update release notes
[skip ci]
2026-01-10 22:03:19 +00:00
Jonathan Ehwald
b4ba7f4652 ⬆️ Migrate to uv (#14676) 2026-01-10 23:02:57 +01:00
github-actions[bot]
c35e1fd4b4 📝 Update release notes
[skip ci]
2026-01-10 21:48:32 +00:00
Motov Yurii
d1c67c0055 🔨 Add LLM translations tool fixer (#14652)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2026-01-10 21:48:08 +00:00
github-actions[bot]
18762e38a9 📝 Update release notes
[skip ci]
2026-01-10 21:35:32 +00:00
Motov Yurii
b1db1395b6 📝 Specify language code for code block (#14656) 2026-01-10 22:35:09 +01:00
1385 changed files with 83014 additions and 53465 deletions

1
.github/labeler.yml vendored
View File

@@ -31,6 +31,7 @@ internal:
- .pre-commit-config.yaml
- pdm_build.py
- requirements*.txt
- uv.lock
- docs/en/data/sponsors.yml
- docs/en/overrides/main.html
- all-globs-to-all-files:

View File

@@ -91,13 +91,13 @@ jobs:
run: uv sync --locked --no-dev --group docs
- name: Update Languages
run: uv run ./scripts/docs.py update-languages
- uses: actions/cache@v4
- uses: actions/cache@v5
with:
key: mkdocs-cards-${{ matrix.lang }}-${{ github.ref }}
path: docs/${{ matrix.lang }}/.cache
- name: Build Docs
run: uv run ./scripts/docs.py build-lang ${{ matrix.lang }}
- uses: actions/upload-artifact@v5
- uses: actions/upload-artifact@v6
with:
name: docs-site-${{ matrix.lang }}
path: ./site/**

View File

@@ -45,7 +45,7 @@ jobs:
run: |
rm -rf ./site
mkdir ./site
- uses: actions/download-artifact@v6
- uses: actions/download-artifact@v7
with:
path: ./site/
pattern: docs-site-*

View File

@@ -41,11 +41,15 @@ jobs:
"message": "As this PR has been waiting for the original user for a while but seems to be inactive, it's now going to be closed. But if there's anyone interested, feel free to create a new PR.",
"reminder": {
"before": "P3D",
"message": "Heads-up: this will be closed in 3 days unless theres new activity."
"message": "Heads-up: this will be closed in 3 days unless there's new activity."
}
},
"invalid": {
"delay": 0,
"message": "This was marked as invalid and will be closed now. If this is an error, please provide additional details."
},
"maybe-ai": {
"delay": 0,
"message": "This was marked as potentially AI generated and will be closed now. If this is an error, please provide additional details, make sure to read the docs about contributing and AI."
}
}

View File

@@ -28,7 +28,7 @@ jobs:
pyproject.toml
uv.lock
- run: uv sync --locked --no-dev --group github-actions
- uses: actions/download-artifact@v6
- uses: actions/download-artifact@v7
with:
name: coverage-html
path: htmlcov

View File

@@ -12,11 +12,6 @@ on:
jobs:
test-redistribute:
runs-on: ubuntu-latest
strategy:
matrix:
package:
- fastapi
- fastapi-slim
steps:
- name: Dump GitHub context
env:
@@ -30,8 +25,6 @@ jobs:
- name: Install build dependencies
run: pip install build
- name: Build source distribution
env:
TIANGOLO_BUILD_PACKAGE: ${{ matrix.package }}
run: python -m build --sdist
- name: Decompress source distribution
run: |
@@ -41,8 +34,6 @@ jobs:
run: |
cd dist/fastapi*/
pip install --group tests --editable .[all]
env:
TIANGOLO_BUILD_PACKAGE: ${{ matrix.package }}
- name: Run source distribution tests
run: |
cd dist/fastapi*/

View File

@@ -14,38 +14,77 @@ on:
env:
UV_NO_SYNC: true
INLINE_SNAPSHOT_DEFAULT_FLAGS: review
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 ]
python-version: [ "3.14" ]
uv-resolution:
- highest
starlette-src:
- starlette-pypi
- starlette-git
include:
- os: ubuntu-latest
python-version: "3.9"
coverage: coverage
- os: macos-latest
python-version: "3.10"
coverage: coverage
uv-resolution: lowest-direct
- os: windows-latest
python-version: "3.12"
coverage: coverage
uv-resolution: lowest-direct
- os: ubuntu-latest
python-version: "3.13"
coverage: coverage
uv-resolution: highest
# Ubuntu with 3.13 needs coverage for CodSpeed benchmarks
- os: ubuntu-latest
python-version: "3.13"
coverage: coverage
uv-resolution: highest
codspeed: codspeed
- os: ubuntu-latest
python-version: "3.14"
coverage: coverage
uv-resolution: highest
starlette-src: starlette-git
fail-fast: false
runs-on: ${{ matrix.os }}
env:
UV_PYTHON: ${{ matrix.python-version }}
UV_RESOLUTION: ${{ matrix.uv-resolution }}
STARLETTE_SRC: ${{ matrix.starlette-src }}
steps:
- name: Dump GitHub context
env:
@@ -64,11 +103,14 @@ jobs:
pyproject.toml
uv.lock
- name: Install Dependencies
run: uv sync --locked --no-dev --group tests --extra all
run: uv sync --no-dev --group tests --extra all
- name: Install Starlette from source
if: matrix.starlette-src == 'starlette-git'
run: uv pip install "git+https://github.com/Kludex/starlette@main"
- run: mkdir coverage
- name: Test
if: matrix.codspeed != 'codspeed'
run: uv run bash scripts/test.sh
run: uv run --no-sync bash scripts/test.sh
env:
COVERAGE_FILE: coverage/.coverage.${{ runner.os }}-py${{ matrix.python-version }}
CONTEXT: ${{ runner.os }}-py${{ matrix.python-version }}
@@ -80,18 +122,19 @@ jobs:
CONTEXT: ${{ runner.os }}-py${{ matrix.python-version }}
with:
mode: simulation
run: uv run coverage run -m pytest tests/ --codspeed
run: uv run --no-sync coverage run -m pytest tests/ --codspeed
# Do not store coverage for all possible combinations to avoid file size max errors in Smokeshow
- name: Store coverage files
if: matrix.coverage == 'coverage'
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v6
with:
name: coverage-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('**/coverage/.coverage.*') }}
path: coverage
include-hidden-files: true
coverage-combine:
needs: [test]
needs:
- test
runs-on: ubuntu-latest
steps:
- name: Dump GitHub context
@@ -112,7 +155,7 @@ jobs:
- name: Install Dependencies
run: uv sync --locked --no-dev --group tests --extra all
- name: Get coverage files
uses: actions/download-artifact@v6
uses: actions/download-artifact@v7
with:
pattern: coverage-*
path: coverage
@@ -121,7 +164,7 @@ jobs:
- run: uv run coverage combine coverage
- run: uv run coverage html --title "Coverage for ${{ github.sha }}"
- name: Store coverage HTML
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v6
with:
name: coverage-html
path: htmlcov
@@ -143,3 +186,4 @@ jobs:
uses: re-actors/alls-green@release/v1
with:
jobs: ${{ toJSON(needs) }}
allowed-skips: coverage-combine,test

View File

@@ -30,6 +30,16 @@ on:
type: string
required: false
default: ""
commit_in_place:
description: Commit changes directly instead of making a PR
type: boolean
required: false
default: false
max:
description: Maximum number of items to translate (e.g. 10)
type: number
required: false
default: 10
jobs:
langs:
@@ -109,3 +119,5 @@ jobs:
LANGUAGE: ${{ matrix.lang }}
EN_PATH: ${{ github.event.inputs.en_path }}
COMMAND: ${{ matrix.command }}
COMMIT_IN_PLACE: ${{ github.event.inputs.commit_in_place }}
MAX: ${{ github.event.inputs.max }}

View File

@@ -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
@@ -58,3 +65,9 @@ repos:
entry: uv run ./scripts/docs.py ensure-non-translated
files: ^docs/(?!en/).*|^scripts/docs\.py$
pass_filenames: false
- id: fix-translations
language: unsupported
name: fix translations
entry: uv run ./scripts/translation_fixer.py fix-pages
files: ^docs/(?!en/).*/docs/.*\.md$

View File

@@ -34,7 +34,7 @@ The key features are:
* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
* **Fast to code**: Increase the speed to develop features by about 200% to 300%. *
* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. *
* **Intuitive**: Great editor support. <abbr title="also known as auto-complete, autocompletion, IntelliSense">Completion</abbr> everywhere. Less time debugging.
* **Intuitive**: Great editor support. <dfn title="also known as auto-complete, autocompletion, IntelliSense">Completion</dfn> everywhere. Less time debugging.
* **Easy**: Designed to be easy to use and learn. Less time reading docs.
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
* **Robust**: Get production-ready code. With automatic interactive documentation.
@@ -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}
@@ -377,7 +371,7 @@ item: Item
* Validation of data:
* Automatic and clear errors when the data is invalid.
* Validation even for deeply nested JSON objects.
* <abbr title="also known as: serialization, parsing, marshalling">Conversion</abbr> of input data: coming from the network to Python data and types. Reading from:
* <dfn title="also known as: serialization, parsing, marshalling">Conversion</dfn> of input data: coming from the network to Python data and types. Reading from:
* JSON.
* Path parameters.
* Query parameters.
@@ -385,7 +379,7 @@ item: Item
* Headers.
* Forms.
* Files.
* <abbr title="also known as: serialization, parsing, marshalling">Conversion</abbr> of output data: converting from Python data and types to network data (as JSON):
* <dfn title="also known as: serialization, parsing, marshalling">Conversion</dfn> of output data: converting from Python data and types to network data (as JSON):
* Convert Python types (`str`, `int`, `float`, `bool`, `list`, etc).
* `datetime` objects.
* `UUID` objects.
@@ -448,7 +442,7 @@ For a more complete example including more features, see the <a href="https://fa
* Declaration of **parameters** from other different places as: **headers**, **cookies**, **form fields** and **files**.
* How to set **validation constraints** as `maximum_length` or `regex`.
* A very powerful and easy to use **<abbr title="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** system.
* A very powerful and easy to use **<dfn title="also known as components, resources, providers, services, injectables">Dependency Injection</dfn>** system.
* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth.
* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic).
* **GraphQL** integration with <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> and other libraries.
@@ -533,7 +527,7 @@ Used by Starlette:
* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - Required if you want to use the `TestClient`.
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`.
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - Required if you want to support form <dfn title="converting the string that comes from an HTTP request into Python data">"parsing"</dfn>, with `request.form()`.
Used by FastAPI:

View File

@@ -35,7 +35,7 @@ Siehe Abschnitt `### Content of code snippets` im allgemeinen Prompt in `scripts
//// tab | Test
Gestern schrieb mein Freund: „Wenn man unkorrekt korrekt schreibt, hat man es unkorrekt geschrieben“. Worauf ich antwortete: „Korrekt, aber unkorrekt ist unkorrekterweise nicht ‚„unkorrekt“‘“.
Gestern schrieb mein Freund: „Wenn man incorrectly korrekt schreibt, hat man es falsch geschrieben“. Worauf ich antwortete: „Korrekt, aber incorrectly ist inkorrekterweise nicht ‚„incorrectly“‘“.
/// note | Hinweis
@@ -189,7 +189,7 @@ Siehe Abschnitt `### Links` im allgemeinen Prompt in `scripts/translate.py`.
////
## HTML „abbr“-Elemente { #html-abbr-elements }
## HTML-„abbr“-Elemente { #html-abbr-elements }
//// tab | Test
@@ -202,11 +202,6 @@ Hier einige Dinge, die in HTML-„abbr“-Elemente gepackt sind (einige sind erf
* <abbr title="XML Web Token">XWT</abbr>
* <abbr title="Paralleles Server-Gateway-Interface">PSGI</abbr>
### Das abbr gibt eine Erklärung { #the-abbr-gives-an-explanation }
* <abbr title="Eine Gruppe von Maschinen, die so konfiguriert sind, dass sie verbunden sind und in irgendeiner Weise zusammenarbeiten.">Cluster</abbr>
* <abbr title="Eine Methode des Machine Learning, die künstliche neuronale Netze mit zahlreichen versteckten Schichten zwischen Eingabe- und Ausgabeschicht verwendet und so eine umfassende interne Struktur entwickelt">Deep Learning</abbr>
### Das abbr gibt eine vollständige Phrase und eine Erklärung { #the-abbr-gives-a-full-phrase-and-an-explanation }
* <abbr title="Mozilla Developer Network Mozilla-Entwicklernetzwerk: Dokumentation für Entwickler, geschrieben von den Firefox-Leuten">MDN</abbr>
@@ -224,6 +219,11 @@ Siehe Abschnitt `### HTML abbr elements` im allgemeinen Prompt in `scripts/trans
////
## HTML „dfn“-Elemente { #html-dfn-elements }
* <dfn title="Eine Gruppe von Maschinen, die so konfiguriert sind, dass sie verbunden sind und in irgendeiner Weise zusammenarbeiten.">Cluster</dfn>
* <dfn title="Eine Methode des Machine Learning, die künstliche neuronale Netze mit zahlreichen versteckten Schichten zwischen Eingabe- und Ausgabeschicht verwendet und so eine umfassende interne Struktur entwickelt">Deep Learning</dfn>
## Überschriften { #headings }
//// tab | Test
@@ -248,7 +248,7 @@ Die einzige strenge Regel für Überschriften ist, dass das LLM den Hash-Teil in
Siehe Abschnitt `### Headings` im allgemeinen Prompt in `scripts/translate.py`.
Für einige sprachspezifische Anweisungen, siehe z. B. den Abschnitt `### Headings` in `docs/de/llm-prompt.md`.
Für einige sprachsspezifische Anweisungen, siehe z. B. den Abschnitt `### Headings` in `docs/de/llm-prompt.md`.
////

View File

@@ -6,13 +6,29 @@ Dazu können Sie die `WSGIMiddleware` verwenden und damit Ihre WSGI-Anwendung wr
## `WSGIMiddleware` verwenden { #using-wsgimiddleware }
Sie müssen `WSGIMiddleware` importieren.
/// info | Info
Dafür muss `a2wsgi` installiert sein, z. B. mit `pip install a2wsgi`.
///
Sie müssen `WSGIMiddleware` aus `a2wsgi` importieren.
Wrappen Sie dann die WSGI-Anwendung (z. B. Flask) mit der Middleware.
Und dann mounten Sie das auf einem Pfad.
{* ../../docs_src/wsgi/tutorial001_py39.py hl[2:3,3] *}
{* ../../docs_src/wsgi/tutorial001_py39.py hl[1,3,23] *}
/// note | Hinweis
Früher wurde empfohlen, `WSGIMiddleware` aus `fastapi.middleware.wsgi` zu verwenden, dies ist jetzt deprecatet.
Stattdessen wird empfohlen, das Paket `a2wsgi` zu verwenden. Die Nutzung bleibt gleich.
Stellen Sie lediglich sicher, dass das Paket `a2wsgi` installiert ist und importieren Sie `WSGIMiddleware` korrekt aus `a2wsgi`.
///
## Es testen { #check-it }

View File

@@ -145,8 +145,6 @@ Es gibt andere Formate und Tools zum Definieren und Installieren von Paketabhän
* Erstellen Sie eine `main.py`-Datei mit:
```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}
```

View File

@@ -161,8 +161,6 @@ $ pip install "fastapi[standard]"
Erstellen Sie eine Datei `main.py` mit:
```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):
Wenn Ihr Code `async` / `await` verwendet, benutzen Sie `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 @@ Sie sehen die alternative automatische Dokumentation (bereitgestellt von <a href
Deklarieren Sie den Body mit Standard-Python-Typen, dank 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}

View File

@@ -56,19 +56,19 @@ from app.routers import items
Die gleiche Dateistruktur mit Kommentaren:
```
```bash
.
├── app # app ist ein Python-Package
│   ├── __init__.py # diese Datei macht app zu einem Python-Package
│   ├── main.py # main-Modul, z. B. import app.main
│   ├── dependencies.py # dependencies-Modul, z. B. import app.dependencies
│   └── routers # routers ist ein Python-Subpackage
│   │ ├── __init__.py # macht routers zu einem Python-Subpackage
│   │ ├── items.py # items-Submodul, z. B. import app.routers.items
│   │ └── users.py # users-Submodul, z. B. import app.routers.users
│   └── internal # internal ist ein Python-Subpackage
│   ├── __init__.py # macht internal zu einem Python-Subpackage
│   └── admin.py # admin-Submodul, z. B. import app.internal.admin
├── app # "app" ist ein Python-Package
│   ├── __init__.py # diese Datei macht "app" zu einem "Python-Package"
│   ├── main.py # "main"-Modul, z. B. import app.main
│   ├── dependencies.py # "dependencies"-Modul, z. B. import app.dependencies
│   └── routers # "routers" ist ein "Python-Subpackage"
│   │ ├── __init__.py # macht "routers" zu einem "Python-Subpackage"
│   │ ├── items.py # "items"-Submodul, z. B. import app.routers.items
│   │ └── users.py # "users"-Submodul, z. B. import app.routers.users
│   └── internal # "internal" ist ein "Python-Subpackage"
│   ├── __init__.py # macht "internal" zu einem "Python-Subpackage"
│   └── admin.py # "admin"-Submodul, z. B. import app.internal.admin
```
## `APIRouter` { #apirouter }
@@ -479,7 +479,7 @@ $ fastapi dev app/main.py
</div>
und öffnen Sie die Dokumentation unter <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
Und öffnen Sie die Dokumentation unter <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
Sie sehen die automatische API-Dokumentation, einschließlich der Pfade aller Submodule, mit den richtigen Pfaden (und Präfixen) und den richtigen Tags:

View File

@@ -1,6 +1,6 @@
# Body Mehrere Parameter { #body-multiple-parameters }
Nun, da wir gesehen haben, wie `Path` und `Query` verwendet werden, schauen wir uns fortgeschrittenere Verwendungsmöglichkeiten von <abbr title="Anfragekörper">Requestbody</abbr>-Deklarationen an.
Nun, da wir gesehen haben, wie `Path` und `Query` verwendet werden, schauen wir uns fortgeschrittenere Verwendungsmöglichkeiten von <abbr title="Requestbody">Requestbody</abbr>-Deklarationen an.
## `Path`-, `Query`- und Body-Parameter vermischen { #mix-path-query-and-body-parameters }
@@ -101,13 +101,13 @@ Natürlich können Sie auch, wann immer Sie das brauchen, weitere Query-Paramete
Da einfache Werte standardmäßig als Query-Parameter interpretiert werden, müssen Sie `Query` nicht explizit hinzufügen, Sie können einfach schreiben:
```Python
q: Union[str, None] = None
q: str | None = None
```
Oder in Python 3.10 und darüber:
Oder in Python 3.9:
```Python
q: str | None = None
q: Union[str, None] = None
```
Zum Beispiel:

View File

@@ -52,7 +52,7 @@ In diesem Fall macht es Sinn, die Tags in einem `Enum` zu speichern.
Sie können eine <abbr title="Zusammenfassung">`summary`</abbr> und eine <abbr title="Beschreibung">`description`</abbr> hinzufügen:
{* ../../docs_src/path_operation_configuration/tutorial003_py310.py hl[18:19] *}
{* ../../docs_src/path_operation_configuration/tutorial003_py310.py hl[17:18] *}
## Beschreibung mittels Docstring { #description-from-docstring }
@@ -70,7 +70,7 @@ Es wird in der interaktiven Dokumentation verwendet:
Sie können die Response mit dem Parameter `response_description` beschreiben:
{* ../../docs_src/path_operation_configuration/tutorial005_py310.py hl[19] *}
{* ../../docs_src/path_operation_configuration/tutorial005_py310.py hl[18] *}
/// info | Info

View File

@@ -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

View File

@@ -65,9 +65,6 @@ bronze:
# - url: https://testdriven.io/courses/tdd-fastapi/
# title: Learn to build high-quality web apps with best practices
# img: https://fastapi.tiangolo.com/img/sponsors/testdriven.svg
- url: https://lambdatest.com/?utm_source=fastapi&utm_medium=partner&utm_campaign=sponsor&utm_term=opensource&utm_content=webpage
title: LambdaTest, AI-Powered Cloud-based Test Orchestration Platform
img: https://fastapi.tiangolo.com/img/sponsors/lambdatest.png
- url: https://requestly.com/fastapi
title: All-in-one platform to Test, Mock and Intercept APIs. Built for speed, privacy and offline support.
img: https://fastapi.tiangolo.com/img/sponsors/requestly.png
- url: https://www.testmu.ai/?utm_source=fastapi&utm_medium=partner&utm_campaign=sponsor&utm_term=opensource&utm_content=webpage
title: TestMu AI. The Native AI-Agentic Cloud Platform to Supercharge Quality Engineering.
img: https://fastapi.tiangolo.com/img/sponsors/testmu.png

View File

@@ -1,91 +1,91 @@
- name: full-stack-fastapi-template
html_url: https://github.com/fastapi/full-stack-fastapi-template
stars: 40534
stars: 41312
owner_login: fastapi
owner_html_url: https://github.com/fastapi
- name: Hello-Python
html_url: https://github.com/mouredev/Hello-Python
stars: 33839
stars: 34206
owner_login: mouredev
owner_html_url: https://github.com/mouredev
- name: serve
html_url: https://github.com/jina-ai/serve
stars: 21819
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: 20457
stars: 20661
owner_login: Zeyi-Lin
owner_html_url: https://github.com/Zeyi-Lin
- name: sqlmodel
html_url: https://github.com/fastapi/sqlmodel
stars: 17458
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: 15923
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: 15763
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: 12477
owner_login: DataTalksClub
owner_html_url: https://github.com/DataTalksClub
- name: SurfSense
html_url: https://github.com/MODSetter/SurfSense
stars: 12299
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: 11351
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: 10932
stars: 11018
owner_login: mjhea0
owner_html_url: https://github.com/mjhea0
- name: XHS-Downloader
html_url: https://github.com/JoeanAmier/XHS-Downloader
stars: 9696
stars: 9938
owner_login: JoeanAmier
owner_html_url: https://github.com/JoeanAmier
- name: polar
html_url: https://github.com/polarsource/polar
stars: 9000
stars: 9348
owner_login: polarsource
owner_html_url: https://github.com/polarsource
- name: FastUI
html_url: https://github.com/pydantic/FastUI
stars: 8938
stars: 8949
owner_login: pydantic
owner_html_url: https://github.com/pydantic
- name: FileCodeBox
html_url: https://github.com/vastsa/FileCodeBox
stars: 7979
stars: 8060
owner_login: vastsa
owner_html_url: https://github.com/vastsa
- name: nonebot2
html_url: https://github.com/nonebot/nonebot2
stars: 7270
stars: 7311
owner_login: nonebot
owner_html_url: https://github.com/nonebot
- name: hatchet
html_url: https://github.com/hatchet-dev/hatchet
stars: 6422
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: 5915
stars: 5970
owner_login: fastapi-users
owner_html_url: https://github.com/fastapi-users
- name: serge
@@ -95,139 +95,144 @@
owner_html_url: https://github.com/serge-chat
- name: strawberry
html_url: https://github.com/strawberry-graphql/strawberry
stars: 4580
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: 4312
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: 4284
stars: 4279
owner_login: chatpire
owner_html_url: https://github.com/chatpire
- name: Kokoro-FastAPI
html_url: https://github.com/remsky/Kokoro-FastAPI
stars: 4241
owner_login: remsky
owner_html_url: https://github.com/remsky
- name: dynaconf
html_url: https://github.com/dynaconf/dynaconf
stars: 4227
stars: 4244
owner_login: dynaconf
owner_html_url: https://github.com/dynaconf
- name: devpush
html_url: https://github.com/hunvreus/devpush
stars: 4173
owner_login: hunvreus
owner_html_url: https://github.com/hunvreus
- 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: 4091
stars: 4086
owner_login: Atri-Labs
owner_html_url: https://github.com/Atri-Labs
- name: logfire
html_url: https://github.com/pydantic/logfire
stars: 3917
stars: 3975
owner_login: pydantic
owner_html_url: https://github.com/pydantic
- name: Yuxi-Know
html_url: https://github.com/xerrors/Yuxi-Know
stars: 3825
owner_login: xerrors
owner_html_url: https://github.com/xerrors
- name: LitServe
html_url: https://github.com/Lightning-AI/LitServe
stars: 3767
stars: 3797
owner_login: Lightning-AI
owner_html_url: https://github.com/Lightning-AI
- name: huma
html_url: https://github.com/danielgtaylor/huma
stars: 3721
stars: 3785
owner_login: danielgtaylor
owner_html_url: https://github.com/danielgtaylor
- name: datamodel-code-generator
html_url: https://github.com/koxudaxi/datamodel-code-generator
stars: 3693
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: 3667
stars: 3697
owner_login: fastapi-admin
owner_html_url: https://github.com/fastapi-admin
- name: farfalle
html_url: https://github.com/rashadphz/farfalle
stars: 3495
stars: 3506
owner_login: rashadphz
owner_html_url: https://github.com/rashadphz
- name: tracecat
html_url: https://github.com/TracecatHQ/tracecat
stars: 3425
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
html_url: https://github.com/docarray/docarray
stars: 3112
stars: 3111
owner_login: docarray
owner_html_url: https://github.com/docarray
- name: mcp-context-forge
html_url: https://github.com/IBM/mcp-context-forge
stars: 3073
owner_login: IBM
owner_html_url: https://github.com/IBM
- name: fastapi-realworld-example-app
html_url: https://github.com/nsidnev/fastapi-realworld-example-app
stars: 3057
stars: 3072
owner_login: nsidnev
owner_html_url: https://github.com/nsidnev
- 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: 2691
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: 2666
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: 2612
stars: 2648
owner_login: sahibzada-allahyar
owner_html_url: https://github.com/sahibzada-allahyar
- name: sqladmin
html_url: https://github.com/aminalaee/sqladmin
stars: 2600
stars: 2637
owner_login: aminalaee
owner_html_url: https://github.com/aminalaee
- name: fastapi-react
html_url: https://github.com/Buuntu/fastapi-react
stars: 2567
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: 2406
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: 2337
@@ -235,261 +240,256 @@
owner_html_url: https://github.com/dot-agent
- name: fastapi-utils
html_url: https://github.com/fastapiutils/fastapi-utils
stars: 2290
stars: 2299
owner_login: fastapiutils
owner_html_url: https://github.com/fastapiutils
- name: langserve
html_url: https://github.com/langchain-ai/langserve
stars: 2240
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: 2234
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: 2144
stars: 2154
owner_login: widgetti
owner_html_url: https://github.com/widgetti
- name: mangum
html_url: https://github.com/Kludex/mangum
stars: 2051
stars: 2071
owner_login: Kludex
owner_html_url: https://github.com/Kludex
- name: NoteDiscovery
html_url: https://github.com/gamosoft/NoteDiscovery
stars: 2038
owner_login: gamosoft
owner_html_url: https://github.com/gamosoft
- name: fastapi_best_architecture
html_url: https://github.com/fastapi-practices/fastapi_best_architecture
stars: 1985
stars: 2036
owner_login: fastapi-practices
owner_html_url: https://github.com/fastapi-practices
- 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: 1930
stars: 1983
owner_login: mizhexiaoxiao
owner_html_url: https://github.com/mizhexiaoxiao
- name: manage-fastapi
html_url: https://github.com/ycd/manage-fastapi
stars: 1893
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: 1885
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: 1859
stars: 1891
owner_login: laurentS
owner_html_url: https://github.com/laurentS
- name: piccolo
html_url: https://github.com/piccolo-orm/piccolo
stars: 1848
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: 1808
owner_login: long2ice
owner_html_url: https://github.com/long2ice
- name: fastapi-langgraph-agent-production-ready-template
html_url: https://github.com/wassim249/fastapi-langgraph-agent-production-ready-template
stars: 1808
owner_login: wassim249
owner_html_url: https://github.com/wassim249
- name: ormar
html_url: https://github.com/collerek/ormar
stars: 1787
stars: 1797
owner_login: collerek
owner_html_url: https://github.com/collerek
- name: FastAPI-boilerplate
html_url: https://github.com/benavlabs/FastAPI-boilerplate
stars: 1755
stars: 1792
owner_login: benavlabs
owner_html_url: https://github.com/benavlabs
- name: termpair
html_url: https://github.com/cs01/termpair
stars: 1725
stars: 1727
owner_login: cs01
owner_html_url: https://github.com/cs01
- name: fastapi-crudrouter
html_url: https://github.com/awtkns/fastapi-crudrouter
stars: 1673
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: 1631
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: 1590
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: 1586
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: 1554
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: 1499
stars: 1512
owner_login: amisadmin
owner_html_url: https://github.com/amisadmin
- name: fastcrud
html_url: https://github.com/benavlabs/fastcrud
stars: 1455
stars: 1471
owner_login: benavlabs
owner_html_url: https://github.com/benavlabs
- name: fastapi-boilerplate
html_url: https://github.com/teamhide/fastapi-boilerplate
stars: 1454
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: 1434
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: 1405
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: 1373
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: 1352
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: 1342
owner_login: atpuxiner
owner_html_url: https://github.com/atpuxiner
- name: bolt-python
html_url: https://github.com/slackapi/bolt-python
stars: 1269
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: 1265
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: 1261
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: 1220
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: 1178
owner_login: langchain-ai
owner_html_url: https://github.com/langchain-ai
- name: restish
html_url: https://github.com/rest-sh/restish
stars: 1156
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: 1145
stars: 1162
owner_login: art049
owner_html_url: https://github.com/art049
- name: aktools
html_url: https://github.com/akfamily/aktools
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: 1155
owner_login: insistence
owner_html_url: https://github.com/insistence
- name: authx
html_url: https://github.com/yezz123/authx
stars: 1130
stars: 1142
owner_login: yezz123
owner_html_url: https://github.com/yezz123
- name: SAG
html_url: https://github.com/Zleap-AI/SAG
stars: 1108
stars: 1110
owner_login: Zleap-AI
owner_html_url: https://github.com/Zleap-AI
- name: RuoYi-Vue3-FastAPI
html_url: https://github.com/insistence/RuoYi-Vue3-FastAPI
stars: 1092
owner_login: insistence
owner_html_url: https://github.com/insistence
- name: aktools
html_url: https://github.com/akfamily/aktools
stars: 1089
owner_login: akfamily
owner_html_url: https://github.com/akfamily
- name: flock
html_url: https://github.com/Onelevenvy/flock
stars: 1060
stars: 1069
owner_login: Onelevenvy
owner_html_url: https://github.com/Onelevenvy
- name: fastapi-observability
html_url: https://github.com/blueswen/fastapi-observability
stars: 1050
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: 1028
stars: 1061
owner_login: SalesforceAIResearch
owner_html_url: https://github.com/SalesforceAIResearch
- name: titiler
html_url: https://github.com/developmentseed/titiler
stars: 1020
stars: 1039
owner_login: developmentseed
owner_html_url: https://github.com/developmentseed
- name: every-pdf
html_url: https://github.com/DDULDDUCK/every-pdf
stars: 1005
stars: 1017
owner_login: DDULDDUCK
owner_html_url: https://github.com/DDULDDUCK
- name: autollm
html_url: https://github.com/viddexa/autollm
stars: 1004
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

View File

@@ -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

View File

@@ -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

View File

@@ -202,11 +202,6 @@ Here some things wrapped in HTML "abbr" elements (Some are invented):
* <abbr title="XML Web Token">XWT</abbr>
* <abbr title="Parallel Server Gateway Interface">PSGI</abbr>
### The abbr gives an explanation { #the-abbr-gives-an-explanation }
* <abbr title="A group of machines that are configured to be connected and work together in some way.">cluster</abbr>
* <abbr title="A method of machine learning that uses artificial neural networks with numerous hidden layers between input and output layers, thereby developing a comprehensive internal structure">Deep Learning</abbr>
### The abbr gives a full phrase and an explanation { #the-abbr-gives-a-full-phrase-and-an-explanation }
* <abbr title="Mozilla Developer Network: documentation for developers, written by the Firefox people">MDN</abbr>
@@ -224,6 +219,11 @@ See section `### HTML abbr elements` in the general prompt in `scripts/translate
////
## HTML "dfn" elements { #html-dfn-elements }
* <dfn title="A group of machines that are configured to be connected and work together in some way.">cluster</dfn>
* <dfn title="A method of machine learning that uses artificial neural networks with numerous hidden layers between input and output layers, thereby developing a comprehensive internal structure">Deep Learning</dfn>
## Headings { #headings }
//// tab | Test

View File

@@ -26,7 +26,7 @@ Each of those response `dict`s can have a key `model`, containing a Pydantic mod
For example, to declare another response with a status code `404` and a Pydantic model `Message`, you can write:
{* ../../docs_src/additional_responses/tutorial001_py39.py hl[18,22] *}
{* ../../docs_src/additional_responses/tutorial001_py310.py hl[18,22] *}
/// note
@@ -203,7 +203,7 @@ For example, you can declare a response with a status code `404` that uses a Pyd
And a response with a status code `200` that uses your `response_model`, but includes a custom `example`:
{* ../../docs_src/additional_responses/tutorial003_py39.py hl[20:31] *}
{* ../../docs_src/additional_responses/tutorial003_py310.py hl[20:31] *}
It will all be combined and included in your OpenAPI, and shown in the API docs:

View File

@@ -18,7 +18,7 @@ Not the class itself (which is already a callable), but an instance of that clas
To do that, we declare a method `__call__`:
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[12] *}
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[12] *}
In this case, this `__call__` is what **FastAPI** will use to check for additional parameters and sub-dependencies, and this is what will be called to pass a value to the parameter in your *path operation function* later.
@@ -26,7 +26,7 @@ In this case, this `__call__` is what **FastAPI** will use to check for addition
And now, we can use `__init__` to declare the parameters of the instance that we can use to "parameterize" the dependency:
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[9] *}
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[9] *}
In this case, **FastAPI** won't ever touch or care about `__init__`, we will use it directly in our code.
@@ -34,7 +34,7 @@ In this case, **FastAPI** won't ever touch or care about `__init__`, we will use
We could create an instance of this class with:
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[18] *}
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[18] *}
And that way we are able to "parameterize" our dependency, that now has `"bar"` inside of it, as the attribute `checker.fixed_content`.
@@ -50,7 +50,7 @@ checker(q="somequery")
...and pass whatever that returns as the value of the dependency in our *path operation function* as the parameter `fixed_content_included`:
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[22] *}
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[22] *}
/// tip
@@ -120,7 +120,7 @@ The exit code, the automatic closing of the `Session` in:
{* ../../docs_src/dependencies/tutorial013_an_py310.py ln[19:21] *}
...would be run after the the response finishes sending the slow data:
...would be run after the response finishes sending the slow data:
{* ../../docs_src/dependencies/tutorial013_an_py310.py ln[30:38] hl[31:33] *}

View File

@@ -0,0 +1,61 @@
# Advanced Python Types { #advanced-python-types }
Here are some additional ideas that might be useful when working with Python types.
## Using `Union` or `Optional` { #using-union-or-optional }
If your code for some reason can't use `|`, for example if it's not in a type annotation but in something like `response_model=`, instead of using the vertical bar (`|`) you can use `Union` from `typing`.
For example, you could declare that something could be a `str` or `None`:
```python
from typing import Union
def say_hi(name: Union[str, None]):
print(f"Hi {name}!")
```
`typing` also has a shortcut to declare that something could be `None`, with `Optional`.
Here's a tip from my very **subjective** point of view:
* 🚨 Avoid using `Optional[SomeType]`
* Instead ✨ **use `Union[SomeType, None]`** ✨.
Both are equivalent and underneath they are the same, but I would recommend `Union` instead of `Optional` because the word "**optional**" would seem to imply that the value is optional, and it actually means "it can be `None`", even if it's not optional and is still required.
I think `Union[SomeType, None]` is more explicit about what it means.
It's just about the words and names. But those words can affect how you and your teammates think about the code.
As an example, let's take this function:
```python
from typing import Optional
def say_hi(name: Optional[str]):
print(f"Hey {name}!")
```
The parameter `name` is defined as `Optional[str]`, but it is **not optional**, you cannot call the function without the parameter:
```Python
say_hi() # Oh, no, this throws an error! 😱
```
The `name` parameter is **still required** (not *optional*) because it doesn't have a default value. Still, `name` accepts `None` as the value:
```Python
say_hi(name=None) # This works, None is valid 🎉
```
The good news is, in most cases, you will be able to simply use `|` to define unions of types:
```python
def say_hi(name: str | None):
print(f"Hey {name}!")
```
So, normally you don't have to worry about names like `Optional` and `Union`. 😎

View File

@@ -32,11 +32,11 @@ For a simple example, let's consider a file structure similar to the one describ
The file `main.py` would have:
{* ../../docs_src/async_tests/app_a_py39/main.py *}
{* ../../docs_src/async_tests/app_a_py310/main.py *}
The file `test_main.py` would have the tests for `main.py`, it could look like this now:
{* ../../docs_src/async_tests/app_a_py39/test_main.py *}
{* ../../docs_src/async_tests/app_a_py310/test_main.py *}
## Run it { #run-it }
@@ -56,7 +56,7 @@ $ pytest
The marker `@pytest.mark.anyio` tells pytest that this test function should be called asynchronously:
{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[7] *}
{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[7] *}
/// tip
@@ -66,7 +66,7 @@ Note that the test function is now `async def` instead of just `def` as before w
Then we can create an `AsyncClient` with the app, and send async requests to it, using `await`.
{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[9:12] *}
{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[9:12] *}
This is the equivalent to:

View File

@@ -44,7 +44,7 @@ $ fastapi run --forwarded-allow-ips="*"
For example, let's say you define a *path operation* `/items/`:
{* ../../docs_src/behind_a_proxy/tutorial001_01_py39.py hl[6] *}
{* ../../docs_src/behind_a_proxy/tutorial001_01_py310.py hl[6] *}
If the client tries to go to `/items`, by default, it would be redirected to `/items/`.
@@ -115,7 +115,7 @@ In this case, the original path `/app` would actually be served at `/api/v1/app`
Even though all your code is written assuming there's just `/app`.
{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[6] *}
{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[6] *}
And the proxy would be **"stripping"** the **path prefix** on the fly before transmitting the request to the app server (probably Uvicorn via FastAPI CLI), keeping your application convinced that it is being served at `/app`, so that you don't have to update all your code to include the prefix `/api/v1`.
@@ -193,7 +193,7 @@ You can get the current `root_path` used by your application for each request, i
Here we are including it in the message just for demonstration purposes.
{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[8] *}
{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[8] *}
Then, if you start Uvicorn with:
@@ -220,7 +220,7 @@ The response would be something like:
Alternatively, if you don't have a way to provide a command line option like `--root-path` or equivalent, you can set the `root_path` parameter when creating your FastAPI app:
{* ../../docs_src/behind_a_proxy/tutorial002_py39.py hl[3] *}
{* ../../docs_src/behind_a_proxy/tutorial002_py310.py hl[3] *}
Passing the `root_path` to `FastAPI` would be the equivalent of passing the `--root-path` command line option to Uvicorn or Hypercorn.
@@ -400,7 +400,7 @@ If you pass a custom list of `servers` and there's a `root_path` (because your A
For example:
{* ../../docs_src/behind_a_proxy/tutorial003_py39.py hl[4:7] *}
{* ../../docs_src/behind_a_proxy/tutorial003_py310.py hl[4:7] *}
Will generate an OpenAPI schema like:
@@ -455,7 +455,7 @@ If you don't specify the `servers` parameter and `root_path` is equal to `/`, th
If you don't want **FastAPI** to include an automatic server using the `root_path`, you can use the parameter `root_path_in_servers=False`:
{* ../../docs_src/behind_a_proxy/tutorial004_py39.py hl[9] *}
{* ../../docs_src/behind_a_proxy/tutorial004_py310.py hl[9] *}
and then it won't include it in the OpenAPI schema.

View File

@@ -30,7 +30,7 @@ This is because by default, FastAPI will inspect every item inside and make sure
But if you are certain that the content that you are returning is **serializable with JSON**, you can pass it directly to the response class and avoid the extra overhead that FastAPI would have by passing your return content through the `jsonable_encoder` before passing it to the response class.
{* ../../docs_src/custom_response/tutorial001b_py39.py hl[2,7] *}
{* ../../docs_src/custom_response/tutorial001b_py310.py hl[2,7] *}
/// info
@@ -55,7 +55,7 @@ To return a response with HTML directly from **FastAPI**, use `HTMLResponse`.
* Import `HTMLResponse`.
* Pass `HTMLResponse` as the parameter `response_class` of your *path operation decorator*.
{* ../../docs_src/custom_response/tutorial002_py39.py hl[2,7] *}
{* ../../docs_src/custom_response/tutorial002_py310.py hl[2,7] *}
/// info
@@ -73,7 +73,7 @@ As seen in [Return a Response directly](response-directly.md){.internal-link tar
The same example from above, returning an `HTMLResponse`, could look like:
{* ../../docs_src/custom_response/tutorial003_py39.py hl[2,7,19] *}
{* ../../docs_src/custom_response/tutorial003_py310.py hl[2,7,19] *}
/// warning
@@ -97,7 +97,7 @@ The `response_class` will then be used only to document the OpenAPI *path operat
For example, it could be something like:
{* ../../docs_src/custom_response/tutorial004_py39.py hl[7,21,23] *}
{* ../../docs_src/custom_response/tutorial004_py310.py hl[7,21,23] *}
In this example, the function `generate_html_response()` already generates and returns a `Response` instead of returning the HTML in a `str`.
@@ -136,7 +136,7 @@ It accepts the following parameters:
FastAPI (actually Starlette) will automatically include a Content-Length header. It will also include a Content-Type header, based on the `media_type` and appending a charset for text types.
{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
### `HTMLResponse` { #htmlresponse }
@@ -146,7 +146,7 @@ Takes some text or bytes and returns an HTML response, as you read above.
Takes some text or bytes and returns a plain text response.
{* ../../docs_src/custom_response/tutorial005_py39.py hl[2,7,9] *}
{* ../../docs_src/custom_response/tutorial005_py310.py hl[2,7,9] *}
### `JSONResponse` { #jsonresponse }
@@ -180,7 +180,7 @@ This requires installing `ujson` for example with `pip install ujson`.
///
{* ../../docs_src/custom_response/tutorial001_py39.py hl[2,7] *}
{* ../../docs_src/custom_response/tutorial001_py310.py hl[2,7] *}
/// tip
@@ -194,14 +194,14 @@ Returns an HTTP redirect. Uses a 307 status code (Temporary Redirect) by default
You can return a `RedirectResponse` directly:
{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *}
{* ../../docs_src/custom_response/tutorial006_py310.py hl[2,9] *}
---
Or you can use it in the `response_class` parameter:
{* ../../docs_src/custom_response/tutorial006b_py39.py hl[2,7,9] *}
{* ../../docs_src/custom_response/tutorial006b_py310.py hl[2,7,9] *}
If you do that, then you can return the URL directly from your *path operation* function.
@@ -211,13 +211,13 @@ In this case, the `status_code` used will be the default one for the `RedirectRe
You can also use the `status_code` parameter combined with the `response_class` parameter:
{* ../../docs_src/custom_response/tutorial006c_py39.py hl[2,7,9] *}
{* ../../docs_src/custom_response/tutorial006c_py310.py hl[2,7,9] *}
### `StreamingResponse` { #streamingresponse }
Takes an async generator or a normal generator/iterator and streams the response body.
{* ../../docs_src/custom_response/tutorial007_py39.py hl[2,14] *}
{* ../../docs_src/custom_response/tutorial007_py310.py hl[2,14] *}
#### Using `StreamingResponse` with file-like objects { #using-streamingresponse-with-file-like-objects }
@@ -227,7 +227,7 @@ That way, you don't have to read it all first in memory, and you can pass that g
This includes many libraries to interact with cloud storage, video processing, and others.
{* ../../docs_src/custom_response/tutorial008_py39.py hl[2,10:12,14] *}
{* ../../docs_src/custom_response/tutorial008_py310.py hl[2,10:12,14] *}
1. This is the generator function. It's a "generator function" because it contains `yield` statements inside.
2. By using a `with` block, we make sure that the file-like object is closed after the generator function is done. So, after it finishes sending the response.
@@ -256,11 +256,11 @@ Takes a different set of arguments to instantiate than the other response types:
File responses will include appropriate `Content-Length`, `Last-Modified` and `ETag` headers.
{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *}
{* ../../docs_src/custom_response/tutorial009_py310.py hl[2,10] *}
You can also use the `response_class` parameter:
{* ../../docs_src/custom_response/tutorial009b_py39.py hl[2,8,10] *}
{* ../../docs_src/custom_response/tutorial009b_py310.py hl[2,8,10] *}
In this case, you can return the file path directly from your *path operation* function.
@@ -274,7 +274,7 @@ Let's say you want it to return indented and formatted JSON, so you want to use
You could create a `CustomORJSONResponse`. The main thing you have to do is create a `Response.render(content)` method that returns the content as `bytes`:
{* ../../docs_src/custom_response/tutorial009c_py39.py hl[9:14,17] *}
{* ../../docs_src/custom_response/tutorial009c_py310.py hl[9:14,17] *}
Now instead of returning:
@@ -300,7 +300,7 @@ The parameter that defines this is `default_response_class`.
In the example below, **FastAPI** will use `ORJSONResponse` by default, in all *path operations*, instead of `JSONResponse`.
{* ../../docs_src/custom_response/tutorial010_py39.py hl[2,4] *}
{* ../../docs_src/custom_response/tutorial010_py310.py hl[2,4] *}
/// tip

View File

@@ -64,7 +64,7 @@ In that case, you can simply swap the standard `dataclasses` with `pydantic.data
6. Here we are returning a dictionary that contains `items` which is a list of dataclasses.
FastAPI is still capable of <abbr title="converting the data to a format that can be transmitted">serializing</abbr> the data to JSON.
FastAPI is still capable of <dfn title="converting the data to a format that can be transmitted">serializing</dfn> the data to JSON.
7. Here the `response_model` is using a type annotation of a list of `Author` dataclasses.

View File

@@ -30,7 +30,7 @@ Let's start with an example and then see it in detail.
We create an async function `lifespan()` with `yield` like this:
{* ../../docs_src/events/tutorial003_py39.py hl[16,19] *}
{* ../../docs_src/events/tutorial003_py310.py hl[16,19] *}
Here we are simulating the expensive *startup* operation of loading the model by putting the (fake) model function in the dictionary with machine learning models before the `yield`. This code will be executed **before** the application **starts taking requests**, during the *startup*.
@@ -48,7 +48,7 @@ Maybe you need to start a new version, or you just got tired of running it. 🤷
The first thing to notice, is that we are defining an async function with `yield`. This is very similar to Dependencies with `yield`.
{* ../../docs_src/events/tutorial003_py39.py hl[14:19] *}
{* ../../docs_src/events/tutorial003_py310.py hl[14:19] *}
The first part of the function, before the `yield`, will be executed **before** the application starts.
@@ -60,7 +60,7 @@ If you check, the function is decorated with an `@asynccontextmanager`.
That converts the function into something called an "**async context manager**".
{* ../../docs_src/events/tutorial003_py39.py hl[1,13] *}
{* ../../docs_src/events/tutorial003_py310.py hl[1,13] *}
A **context manager** in Python is something that you can use in a `with` statement, for example, `open()` can be used as a context manager:
@@ -82,7 +82,7 @@ In our code example above, we don't use it directly, but we pass it to FastAPI f
The `lifespan` parameter of the `FastAPI` app takes an **async context manager**, so we can pass our new `lifespan` async context manager to it.
{* ../../docs_src/events/tutorial003_py39.py hl[22] *}
{* ../../docs_src/events/tutorial003_py310.py hl[22] *}
## Alternative Events (deprecated) { #alternative-events-deprecated }
@@ -104,7 +104,7 @@ These functions can be declared with `async def` or normal `def`.
To add a function that should be run before the application starts, declare it with the event `"startup"`:
{* ../../docs_src/events/tutorial001_py39.py hl[8] *}
{* ../../docs_src/events/tutorial001_py310.py hl[8] *}
In this case, the `startup` event handler function will initialize the items "database" (just a `dict`) with some values.
@@ -116,7 +116,7 @@ And your application won't start receiving requests until all the `startup` even
To add a function that should be run when the application is shutting down, declare it with the event `"shutdown"`:
{* ../../docs_src/events/tutorial002_py39.py hl[6] *}
{* ../../docs_src/events/tutorial002_py310.py hl[6] *}
Here, the `shutdown` event handler function will write a text line `"Application shutdown"` to a file `log.txt`.

View File

@@ -40,7 +40,7 @@ Some of these solutions may also be open source or offer free tiers, so you can
Let's start with a simple FastAPI application:
{* ../../docs_src/generate_clients/tutorial001_py39.py hl[7:9,12:13,16:17,21] *}
{* ../../docs_src/generate_clients/tutorial001_py310.py hl[7:9,12:13,16:17,21] *}
Notice that the *path operations* define the models they use for request payload and response payload, using the models `Item` and `ResponseMessage`.
@@ -98,7 +98,7 @@ In many cases, your FastAPI app will be bigger, and you will probably use tags t
For example, you could have a section for **items** and another section for **users**, and they could be separated by tags:
{* ../../docs_src/generate_clients/tutorial002_py39.py hl[21,26,34] *}
{* ../../docs_src/generate_clients/tutorial002_py310.py hl[21,26,34] *}
### Generate a TypeScript Client with Tags { #generate-a-typescript-client-with-tags }
@@ -145,7 +145,7 @@ For example, here it is using the first tag (you will probably have only one tag
You can then pass that custom function to **FastAPI** as the `generate_unique_id_function` parameter:
{* ../../docs_src/generate_clients/tutorial003_py39.py hl[6:7,10] *}
{* ../../docs_src/generate_clients/tutorial003_py310.py hl[6:7,10] *}
### Generate a TypeScript Client with Custom Operation IDs { #generate-a-typescript-client-with-custom-operation-ids }
@@ -167,7 +167,7 @@ But for the generated client, we could **modify** the OpenAPI operation IDs righ
We could download the OpenAPI JSON to a file `openapi.json` and then we could **remove that prefixed tag** with a script like this:
{* ../../docs_src/generate_clients/tutorial004_py39.py *}
{* ../../docs_src/generate_clients/tutorial004_py310.py *}
//// tab | Node.js

View File

@@ -57,13 +57,13 @@ Enforces that all incoming requests must either be `https` or `wss`.
Any incoming request to `http` or `ws` will be redirected to the secure scheme instead.
{* ../../docs_src/advanced_middleware/tutorial001_py39.py hl[2,6] *}
{* ../../docs_src/advanced_middleware/tutorial001_py310.py hl[2,6] *}
## `TrustedHostMiddleware` { #trustedhostmiddleware }
Enforces that all incoming requests have a correctly set `Host` header, in order to guard against HTTP Host Header attacks.
{* ../../docs_src/advanced_middleware/tutorial002_py39.py hl[2,6:8] *}
{* ../../docs_src/advanced_middleware/tutorial002_py310.py hl[2,6:8] *}
The following arguments are supported:
@@ -78,7 +78,7 @@ Handles GZip responses for any request that includes `"gzip"` in the `Accept-Enc
The middleware will handle both standard and streaming responses.
{* ../../docs_src/advanced_middleware/tutorial003_py39.py hl[2,6] *}
{* ../../docs_src/advanced_middleware/tutorial003_py310.py hl[2,6] *}
The following arguments are supported:

View File

@@ -32,7 +32,7 @@ Webhooks are available in OpenAPI 3.1.0 and above, supported by FastAPI `0.99.0`
When you create a **FastAPI** application, there is a `webhooks` attribute that you can use to define *webhooks*, the same way you would define *path operations*, for example with `@app.webhooks.post()`.
{* ../../docs_src/openapi_webhooks/tutorial001_py39.py hl[9:13,36:53] *}
{* ../../docs_src/openapi_webhooks/tutorial001_py310.py hl[9:13,36:53] *}
The webhooks that you define will end up in the **OpenAPI** schema and the automatic **docs UI**.

View File

@@ -12,7 +12,7 @@ You can set the OpenAPI `operationId` to be used in your *path operation* with t
You would have to make sure that it is unique for each operation.
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py310.py hl[6] *}
### Using the *path operation function* name as the operationId { #using-the-path-operation-function-name-as-the-operationid }
@@ -20,7 +20,7 @@ If you want to use your APIs' function names as `operationId`s, you can iterate
You should do it after adding all your *path operations*.
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py310.py hl[2, 12:21, 24] *}
/// tip
@@ -40,7 +40,7 @@ Even if they are in different modules (Python files).
To exclude a *path operation* from the generated OpenAPI schema (and thus, from the automatic documentation systems), use the parameter `include_in_schema` and set it to `False`:
{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py310.py hl[6] *}
## Advanced description from docstring { #advanced-description-from-docstring }
@@ -92,7 +92,7 @@ You can extend the OpenAPI schema for a *path operation* using the parameter `op
This `openapi_extra` can be helpful, for example, to declare [OpenAPI Extensions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions):
{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py39.py hl[6] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py310.py hl[6] *}
If you open the automatic API docs, your extension will show up at the bottom of the specific *path operation*.
@@ -139,9 +139,9 @@ For example, you could decide to read and validate the request with your own cod
You could do that with `openapi_extra`:
{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py310.py hl[19:36, 39:40] *}
In this example, we didn't declare any Pydantic model. In fact, the request body is not even <abbr title="converted from some plain format, like bytes, into Python objects">parsed</abbr> as JSON, it is read directly as `bytes`, and the function `magic_data_reader()` would be in charge of parsing it in some way.
In this example, we didn't declare any Pydantic model. In fact, the request body is not even <dfn title="converted from some plain format, like bytes, into Python objects">parsed</dfn> as JSON, it is read directly as `bytes`, and the function `magic_data_reader()` would be in charge of parsing it in some way.
Nevertheless, we can declare the expected schema for the request body.
@@ -153,7 +153,7 @@ And you could do this even if the data type in the request is not JSON.
For example, in this application we don't use FastAPI's integrated functionality to extract the JSON Schema from Pydantic models nor the automatic validation for JSON. In fact, we are declaring the request content type as YAML, not JSON:
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[15:20, 22] *}
Nevertheless, although we are not using the default integrated functionality, we are still using a Pydantic model to manually generate the JSON Schema for the data that we want to receive in YAML.
@@ -161,7 +161,7 @@ Then we use the request directly, and extract the body as `bytes`. This means th
And then in our code, we parse that YAML content directly, and then we are again using the same Pydantic model to validate the YAML content:
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[24:31] *}
/// tip

View File

@@ -20,7 +20,7 @@ You can declare a parameter of type `Response` in your *path operation function*
And then you can set the `status_code` in that *temporal* response object.
{* ../../docs_src/response_change_status_code/tutorial001_py39.py hl[1,9,12] *}
{* ../../docs_src/response_change_status_code/tutorial001_py310.py hl[1,9,12] *}
And then you can return any object you need, as you normally would (a `dict`, a database model, etc).

View File

@@ -6,7 +6,7 @@ You can declare a parameter of type `Response` in your *path operation function*
And then you can set cookies in that *temporal* response object.
{* ../../docs_src/response_cookies/tutorial002_py39.py hl[1, 8:9] *}
{* ../../docs_src/response_cookies/tutorial002_py310.py hl[1, 8:9] *}
And then you can return any object you need, as you normally would (a `dict`, a database model, etc).
@@ -24,7 +24,7 @@ To do that, you can create a response as described in [Return a Response Directl
Then set Cookies in it, and then return it:
{* ../../docs_src/response_cookies/tutorial001_py39.py hl[10:12] *}
{* ../../docs_src/response_cookies/tutorial001_py310.py hl[10:12] *}
/// tip

View File

@@ -54,7 +54,7 @@ Let's say that you want to return an <a href="https://en.wikipedia.org/wiki/XML"
You could put your XML content in a string, put that in a `Response`, and return it:
{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
## Notes { #notes }

View File

@@ -6,7 +6,7 @@ You can declare a parameter of type `Response` in your *path operation function*
And then you can set headers in that *temporal* response object.
{* ../../docs_src/response_headers/tutorial002_py39.py hl[1, 7:8] *}
{* ../../docs_src/response_headers/tutorial002_py310.py hl[1, 7:8] *}
And then you can return any object you need, as you normally would (a `dict`, a database model, etc).
@@ -22,7 +22,7 @@ You can also add headers when you return a `Response` directly.
Create a response as described in [Return a Response Directly](response-directly.md){.internal-link target=_blank} and pass the headers as an additional parameter:
{* ../../docs_src/response_headers/tutorial001_py39.py hl[10:12] *}
{* ../../docs_src/response_headers/tutorial001_py310.py hl[10:12] *}
/// note | Technical Details

View File

@@ -20,7 +20,7 @@ Then, when you type that username and password, the browser sends them in the he
* It returns an object of type `HTTPBasicCredentials`:
* It contains the `username` and `password` sent.
{* ../../docs_src/security/tutorial006_an_py39.py hl[4,8,12] *}
{* ../../docs_src/security/tutorial006_an_py310.py hl[4,8,12] *}
When you try to open the URL for the first time (or click the "Execute" button in the docs) the browser will ask you for your username and password:
@@ -40,7 +40,7 @@ To handle that, we first convert the `username` and `password` to `bytes` encodi
Then we can use `secrets.compare_digest()` to ensure that `credentials.username` is `"stanleyjobson"`, and that `credentials.password` is `"swordfish"`.
{* ../../docs_src/security/tutorial007_an_py39.py hl[1,12:24] *}
{* ../../docs_src/security/tutorial007_an_py310.py hl[1,12:24] *}
This would be similar to:
@@ -104,4 +104,4 @@ That way, using `secrets.compare_digest()` in your application code, it will be
After detecting that the credentials are incorrect, return an `HTTPException` with a status code 401 (the same returned when no credentials are provided) and add the header `WWW-Authenticate` to make the browser show the login prompt again:
{* ../../docs_src/security/tutorial007_an_py39.py hl[26:30] *}
{* ../../docs_src/security/tutorial007_an_py310.py hl[26:30] *}

View File

@@ -54,7 +54,7 @@ The same way as with Pydantic models, you declare class attributes with type ann
You can use all the same validation features and tools you use for Pydantic models, like different data types and additional validations with `Field()`.
{* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *}
{* ../../docs_src/settings/tutorial001_py310.py hl[2,5:8,11] *}
/// tip
@@ -70,7 +70,7 @@ Next it will convert and validate the data. So, when you use that `settings` obj
Then you can use the new `settings` object in your application:
{* ../../docs_src/settings/tutorial001_py39.py hl[18:20] *}
{* ../../docs_src/settings/tutorial001_py310.py hl[18:20] *}
### Run the server { #run-the-server }
@@ -104,11 +104,11 @@ You could put those settings in another module file as you saw in [Bigger Applic
For example, you could have a file `config.py` with:
{* ../../docs_src/settings/app01_py39/config.py *}
{* ../../docs_src/settings/app01_py310/config.py *}
And then use it in a file `main.py`:
{* ../../docs_src/settings/app01_py39/main.py hl[3,11:13] *}
{* ../../docs_src/settings/app01_py310/main.py hl[3,11:13] *}
/// tip
@@ -126,7 +126,7 @@ This could be especially useful during testing, as it's very easy to override a
Coming from the previous example, your `config.py` file could look like:
{* ../../docs_src/settings/app02_an_py39/config.py hl[10] *}
{* ../../docs_src/settings/app02_an_py310/config.py hl[10] *}
Notice that now we don't create a default instance `settings = Settings()`.
@@ -134,7 +134,7 @@ Notice that now we don't create a default instance `settings = Settings()`.
Now we create a dependency that returns a new `config.Settings()`.
{* ../../docs_src/settings/app02_an_py39/main.py hl[6,12:13] *}
{* ../../docs_src/settings/app02_an_py310/main.py hl[6,12:13] *}
/// tip
@@ -146,13 +146,13 @@ For now you can assume `get_settings()` is a normal function.
And then we can require it from the *path operation function* as a dependency and use it anywhere we need it.
{* ../../docs_src/settings/app02_an_py39/main.py hl[17,19:21] *}
{* ../../docs_src/settings/app02_an_py310/main.py hl[17,19:21] *}
### Settings and testing { #settings-and-testing }
Then it would be very easy to provide a different settings object during testing by creating a dependency override for `get_settings`:
{* ../../docs_src/settings/app02_an_py39/test_main.py hl[9:10,13,21] *}
{* ../../docs_src/settings/app02_an_py310/test_main.py hl[9:10,13,21] *}
In the dependency override we set a new value for the `admin_email` when creating the new `Settings` object, and then we return that new object.
@@ -193,7 +193,7 @@ APP_NAME="ChimichangApp"
And then update your `config.py` with:
{* ../../docs_src/settings/app03_an_py39/config.py hl[9] *}
{* ../../docs_src/settings/app03_an_py310/config.py hl[9] *}
/// tip
@@ -226,7 +226,7 @@ we would create that object for each request, and we would be reading the `.env`
But as we are using the `@lru_cache` decorator on top, the `Settings` object will be created only once, the first time it's called. ✔️
{* ../../docs_src/settings/app03_an_py39/main.py hl[1,11] *}
{* ../../docs_src/settings/app03_an_py310/main.py hl[1,11] *}
Then for any subsequent call of `get_settings()` in the dependencies for the next requests, instead of executing the internal code of `get_settings()` and creating a new `Settings` object, it will return the same object that was returned on the first call, again and again.

View File

@@ -10,7 +10,7 @@ If you need to have two independent FastAPI applications, with their own indepen
First, create the main, top-level, **FastAPI** application, and its *path operations*:
{* ../../docs_src/sub_applications/tutorial001_py39.py hl[3, 6:8] *}
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[3, 6:8] *}
### Sub-application { #sub-application }
@@ -18,7 +18,7 @@ Then, create your sub-application, and its *path operations*.
This sub-application is just another standard FastAPI application, but this is the one that will be "mounted":
{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 14:16] *}
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 14:16] *}
### Mount the sub-application { #mount-the-sub-application }
@@ -26,7 +26,7 @@ In your top-level application, `app`, mount the sub-application, `subapi`.
In this case, it will be mounted at the path `/subapi`:
{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 19] *}
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 19] *}
### Check the automatic API docs { #check-the-automatic-api-docs }

View File

@@ -27,7 +27,7 @@ $ pip install jinja2
* Declare a `Request` parameter in the *path operation* that will return a template.
* Use the `templates` you created to render and return a `TemplateResponse`, pass the name of the template, the request object, and a "context" dictionary with key-value pairs to be used inside of the Jinja2 template.
{* ../../docs_src/templates/tutorial001_py39.py hl[4,11,15:18] *}
{* ../../docs_src/templates/tutorial001_py310.py hl[4,11,15:18] *}
/// note

View File

@@ -2,11 +2,11 @@
When you need `lifespan` to run in your tests, you can use the `TestClient` with a `with` statement:
{* ../../docs_src/app_testing/tutorial004_py39.py hl[9:15,18,27:28,30:32,41:43] *}
{* ../../docs_src/app_testing/tutorial004_py310.py hl[9:15,18,27:28,30:32,41:43] *}
You can read more details about the ["Running lifespan in tests in the official Starlette documentation site."](https://www.starlette.dev/lifespan/#running-lifespan-in-tests)
For the deprecated `startup` and `shutdown` events, you can use the `TestClient` as follows:
{* ../../docs_src/app_testing/tutorial003_py39.py hl[9:12,20:24] *}
{* ../../docs_src/app_testing/tutorial003_py310.py hl[9:12,20:24] *}

View File

@@ -4,7 +4,7 @@ You can use the same `TestClient` to test WebSockets.
For this, you use the `TestClient` in a `with` statement, connecting to the WebSocket:
{* ../../docs_src/app_testing/tutorial002_py39.py hl[27:31] *}
{* ../../docs_src/app_testing/tutorial002_py310.py hl[27:31] *}
/// note

View File

@@ -29,7 +29,7 @@ Let's imagine you want to get the client's IP address/host inside of your *path
For that you need to access the request directly.
{* ../../docs_src/using_request_directly/tutorial001_py39.py hl[1,7:8] *}
{* ../../docs_src/using_request_directly/tutorial001_py310.py hl[1,7:8] *}
By declaring a *path operation function* parameter with the type being the `Request` **FastAPI** will know to pass the `Request` in that parameter.

View File

@@ -38,13 +38,13 @@ In production you would have one of the options above.
But it's the simplest way to focus on the server-side of WebSockets and have a working example:
{* ../../docs_src/websockets/tutorial001_py39.py hl[2,6:38,41:43] *}
{* ../../docs_src/websockets/tutorial001_py310.py hl[2,6:38,41:43] *}
## Create a `websocket` { #create-a-websocket }
In your **FastAPI** application, create a `websocket`:
{* ../../docs_src/websockets/tutorial001_py39.py hl[1,46:47] *}
{* ../../docs_src/websockets/tutorial001_py310.py hl[1,46:47] *}
/// note | Technical Details
@@ -58,7 +58,7 @@ You could also use `from starlette.websockets import WebSocket`.
In your WebSocket route you can `await` for messages and send messages.
{* ../../docs_src/websockets/tutorial001_py39.py hl[48:52] *}
{* ../../docs_src/websockets/tutorial001_py310.py hl[48:52] *}
You can receive and send binary, text, and JSON data.
@@ -154,7 +154,7 @@ With that you can connect the WebSocket and then send and receive messages:
When a WebSocket connection is closed, the `await websocket.receive_text()` will raise a `WebSocketDisconnect` exception, which you can then catch and handle like in this example.
{* ../../docs_src/websockets/tutorial003_py39.py hl[79:81] *}
{* ../../docs_src/websockets/tutorial003_py310.py hl[79:81] *}
To try it out:

View File

@@ -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_py310.py hl[1,3,23] *}
/// note
Previously, it was recommended to use `WSGIMiddleware` from `fastapi.middleware.wsgi`, but it is now deprecated.
Its 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 }

View File

@@ -137,7 +137,7 @@ There are several Flask REST frameworks, but after investing the time and work i
### <a href="https://marshmallow.readthedocs.io/en/stable/" class="external-link" target="_blank">Marshmallow</a> { #marshmallow }
One of the main features needed by API systems is data "<abbr title="also called marshalling, conversion">serialization</abbr>" which is taking data from the code (Python) and converting it into something that can be sent through the network. For example, converting an object containing data from a database into a JSON object. Converting `datetime` objects into strings, etc.
One of the main features needed by API systems is data "<dfn title="also called marshalling, conversion">serialization</dfn>" which is taking data from the code (Python) and converting it into something that can be sent through the network. For example, converting an object containing data from a database into a JSON object. Converting `datetime` objects into strings, etc.
Another big feature needed by APIs is data validation, making sure that the data is valid, given certain parameters. For example, that some field is an `int`, and not some random string. This is especially useful for incoming data.
@@ -145,7 +145,7 @@ Without a data validation system, you would have to do all the checks by hand, i
These features are what Marshmallow was built to provide. It is a great library, and I have used it a lot before.
But it was created before there existed Python type hints. So, to define every <abbr title="the definition of how data should be formed">schema</abbr> you need to use specific utils and classes provided by Marshmallow.
But it was created before there existed Python type hints. So, to define every <dfn title="the definition of how data should be formed">schema</dfn> you need to use specific utils and classes provided by Marshmallow.
/// check | Inspired **FastAPI** to
@@ -155,7 +155,7 @@ Use code to define "schemas" that provide data types and validation, automatical
### <a href="https://webargs.readthedocs.io/en/latest/" class="external-link" target="_blank">Webargs</a> { #webargs }
Another big feature required by APIs is <abbr title="reading and converting to Python data">parsing</abbr> data from incoming requests.
Another big feature required by APIs is <dfn title="reading and converting to Python data">parsing</dfn> data from incoming requests.
Webargs is a tool that was made to provide that on top of several frameworks, including Flask.
@@ -419,7 +419,7 @@ Handle all the data validation, data serialization and automatic model documenta
### <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> { #starlette }
Starlette is a lightweight <abbr title="The new standard for building asynchronous Python web applications">ASGI</abbr> framework/toolkit, which is ideal for building high-performance asyncio services.
Starlette is a lightweight <dfn title="The new standard for building asynchronous Python web applications">ASGI</dfn> framework/toolkit, which is ideal for building high-performance asyncio services.
It is very simple and intuitive. It's designed to be easily extensible, and have modular components.

View File

@@ -13,7 +13,7 @@ Create a virtual environment and install the required packages with <a href="htt
<div class="termy">
```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.
///
@@ -177,252 +177,85 @@ as Uvicorn by default will use the port `8000`, the documentation on port `8008`
### Translations
/// warning | Attention
**Update on Translations**
We're updating the way we handle documentation translations.
Until now, we invited community members to translate pages via pull requests, which were then reviewed by at least two native speakers. While this has helped bring FastAPI to many more users, weve also run into several challenges - some languages have only a few translated pages, others are outdated and hard to maintain over time.
To improve this, were working on automation tools 🤖 to manage translations more efficiently. Once ready, documentation will be machine-translated and still reviewed by at least two native speakers ✅ before publishing. This will allow us to keep translations up-to-date while reducing the review burden on maintainers.
Whats changing now:
* 🚫 Were no longer accepting new community-submitted translation PRs.
* ⏳ Existing open PRs will be reviewed and can still be merged if completed within the next 3 weeks (since July 11 2025).
* 🌐 In the future, we will only support languages where at least three active native speakers are available to review and maintain translations.
This transition will help us keep translations more consistent and timely while better supporting our contributors 🙌. Thank you to everyone who has contributed so far — your help has been invaluable! 💖
///
Help with translations is VERY MUCH appreciated! And it can't be done without the help from the community. 🌎 🚀
Here are the steps to help with translations.
Translation pull requests are made by LLMs guided with prompts designed by the FastAPI team together with the community of native speakers for each supported language.
#### Tips and guidelines
#### LLM Prompt per Language
* Check the currently <a href="https://github.com/fastapi/fastapi/pulls" class="external-link" target="_blank">existing pull requests</a> for your language. You can filter the pull requests by the ones with the label for your language. For example, for Spanish, the label is <a href="https://github.com/fastapi/fastapi/pulls?q=is%3Aopen+sort%3Aupdated-desc+label%3Alang-es+label%3Aawaiting-review" class="external-link" target="_blank">`lang-es`</a>.
Each language has a directory: <a href="https://github.com/fastapi/fastapi/tree/master/docs" class="external-link" target="_blank">https://github.com/fastapi/fastapi/tree/master/docs</a>, in it you can see a file `llm-prompt.md` with the prompt specific for that language.
* Review those pull requests, requesting changes or approving them. For the languages I don't speak, I'll wait for several others to review the translation before merging.
For example, for Spanish, the prompt is at: <a href="https://github.com/fastapi/fastapi/blob/master/docs/es/llm-prompt.md" class="external-link" target="_blank">`docs/es/llm-prompt.md`</a>.
If you see mistakes in your language, you can make suggestions to the prompt in that file for your language, and request the specific pages you would like to re-generate after the changes.
#### Reviewing Translation PRs
You can also check the currently <a href="https://github.com/fastapi/fastapi/pulls" class="external-link" target="_blank">existing pull requests</a> for your language. You can filter the pull requests by the ones with the label for your language. For example, for Spanish, the label is <a href="https://github.com/fastapi/fastapi/pulls?q=is%3Aopen+sort%3Aupdated-desc+label%3Alang-es+label%3Aawaiting-review" class="external-link" target="_blank">`lang-es`</a>.
When reviewing a pull request, it's better not to suggest changes in the same pull request, because it is LLM generated, and it won't be possible to make sure that small individual changes are replicated in other similar sections, or that they are preserved when translating the same content again.
Instead of adding suggestions to the translation PR, make the suggestions to the LLM prompt file for that language, in a new PR. For example, for Spanish, the LLM prompt file is at: <a href="https://github.com/fastapi/fastapi/blob/master/docs/es/llm-prompt.md" class="external-link" target="_blank">`docs/es/llm-prompt.md`</a>.
/// tip
You can <a href="https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request" class="external-link" target="_blank">add comments with change suggestions</a> to existing pull requests.
Check the docs about <a href="https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-request-reviews" class="external-link" target="_blank">adding a pull request review</a> to approve it or request changes.
///
* Check if there's a <a href="https://github.com/fastapi/fastapi/discussions/categories/translations" class="external-link" target="_blank">GitHub Discussion</a> to coordinate translations for your language. You can subscribe to it, and when there's a new pull request to review, an automatic comment will be added to the discussion.
#### Subscribe to Notifications for Your Language
* If you translate pages, add a single pull request per page translated. That will make it much easier for others to review it.
Check if there's a <a href="https://github.com/fastapi/fastapi/discussions/categories/translations" class="external-link" target="_blank">GitHub Discussion</a> to coordinate translations for your language. You can subscribe to it, and when there's a new pull request to review, an automatic comment will be added to the discussion.
* To check the 2-letter code for the language you want to translate, you can use the table <a href="https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes" class="external-link" target="_blank">List of ISO 639-1 codes</a>.
#### Existing language
Let's say you want to translate a page for a language that already has translations for some pages, like Spanish.
In the case of Spanish, the 2-letter code is `es`. So, the directory for Spanish translations is located at `docs/es/`.
/// tip
The main ("official") language is English, located at `docs/en/`.
///
Now run the live server for the docs in Spanish:
<div class="termy">
```console
// Use the command "live" and pass the language code as a CLI argument
$ python ./scripts/docs.py live es
<span style="color: green;">[INFO]</span> Serving on http://127.0.0.1:8008
<span style="color: green;">[INFO]</span> Start watching changes
<span style="color: green;">[INFO]</span> Start detecting changes
```
</div>
/// tip
Alternatively, you can perform the same steps that scripts does manually.
Go into the language directory, for the Spanish translations it's at `docs/es/`:
```console
$ cd docs/es/
```
Then run `mkdocs` in that directory:
```console
$ mkdocs serve --dev-addr 127.0.0.1:8008
```
///
Now you can go to <a href="http://127.0.0.1:8008" class="external-link" target="_blank">http://127.0.0.1:8008</a> and see your changes live.
You will see that every language has all the pages. But some pages are not translated and have an info box at the top, about the missing translation.
Now let's say that you want to add a translation for the section [Features](features.md){.internal-link target=_blank}.
* Copy the file at:
```
docs/en/docs/features.md
```
* Paste it in exactly the same location but for the language you want to translate, e.g.:
```
docs/es/docs/features.md
```
/// tip
Notice that the only change in the path and file name is the language code, from `en` to `es`.
///
If you go to your browser you will see that now the docs show your new section (the info box at the top is gone). 🎉
Now you can translate it all and see how it looks as you save the file.
#### Don't Translate these Pages
🚨 Don't translate:
* Files under `reference/`
* `release-notes.md`
* `fastapi-people.md`
* `external-links.md`
* `newsletter.md`
* `management-tasks.md`
* `management.md`
* `contributing.md`
Some of these files are updated very frequently and a translation would always be behind, or they include the main content from English source files, etc.
To check the 2-letter code for the language you want to translate, you can use the table <a href="https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes" class="external-link" target="_blank">List of ISO 639-1 codes</a>.
#### Request a New Language
Let's say that you want to request translations for a language that is not yet translated, not even some pages. For example, Latin.
If there is no discussion for that language, you can start by requesting the new language. For that, you can follow these steps:
* The first step would be for you to find other 2 people that would be willing to be reviewing translation PRs for that language with you.
* Once there are at least 3 people that would be willing to commit to help maintain that language, you can continue the next steps.
* Create a new discussion following the template.
* Get a few native speakers to comment on the discussion and commit to help review translations for that language.
* Tag the other 2 people that will help with the language, and ask them to confirm there they will help.
Once there are several people in the discussion, the FastAPI team can evaluate it and can make it an official translation.
Then the docs will be automatically translated using AI, and the team of native speakers can review the translation, and help tweak the AI prompts.
Then the docs will be automatically translated using LLMs, and the team of native speakers can review the translation, and help tweak the LLM prompts.
Once there's a new translation, for example if docs are updated or there's a new section, there will be a comment in the same discussion with the link to the new translation to review.
#### New Language
## Automated Code and AI
/// note
You are encouraged to use all the tools you want to do your work and contribute as efficiently as possible, this includes AI (LLM) tools, etc. Nevertheless, contributions should have meaningful human intervention, judgement, context, etc.
These steps will be performed by the FastAPI team.
If the **human effort** put in a PR, e.g. writing LLM prompts, is **less** than the **effort we would need to put** to **review it**, please **don't** submit the PR.
///
Think of it this way: we can already write LLM prompts or run automated tools ourselves, and that would be faster than reviewing external PRs.
Checking the link from above (List of ISO 639-1 codes), you can see that the 2-letter code for Latin is `la`.
### Closing Automated and AI PRs
Now you can create a new directory for the new language, running the following script:
If we see PRs that seem AI generated or automated in similar ways, we'll flag them and close them.
<div class="termy">
The same applies to comments and descriptions, please don't copy paste the content generated by an LLM.
```console
// Use the command new-lang, pass the language code as a CLI argument
$ python ./scripts/docs.py new-lang la
### Human Effort Denial of Service
Successfully initialized: docs/la
```
Using automated tools and AI to submit PRs or comments that we have to carefully review and handle would be the equivalent of a <a href="https://en.wikipedia.org/wiki/Denial-of-service_attack" class="external-link" target="_blank">Denial-of-service attack</a> on our human effort.
</div>
It would be very little effort from the person submitting the PR (an LLM prompt) that generates a large amount of effort on our side (carefully reviewing code).
Now you can check in your code editor the newly created directory `docs/la/`.
Please don't do that.
That command created a file `docs/la/mkdocs.yml` with a simple config that inherits everything from the `en` version:
We'll need to block accounts that spam us with repeated automated PRs or comments.
```yaml
INHERIT: ../en/mkdocs.yml
```
### Use Tools Wisely
/// tip
As Uncle Ben said:
You could also simply create that file with those contents manually.
<blockquote>
With great <strike>power</strike> <strong>tools</strong> comes great responsibility.
</blockquote>
///
Avoid inadvertently doing harm.
That command also created a dummy file `docs/la/index.md` for the main page, you can start by translating that one.
You can continue with the previous instructions for an "Existing Language" for that process.
You can make the first pull request with those two files, `docs/la/mkdocs.yml` and `docs/la/index.md`. 🎉
#### Preview the result
As already mentioned above, you can use the `./scripts/docs.py` with the `live` command to preview the results (or `mkdocs serve`).
Once you are done, you can also test it all as it would look online, including all the other languages.
To do that, first build all the docs:
<div class="termy">
```console
// Use the command "build-all", this will take a bit
$ python ./scripts/docs.py build-all
Building docs for: en
Building docs for: es
Successfully built docs for: es
```
</div>
This builds all those independent MkDocs sites for each language, combines them, and generates the final output at `./site/`.
Then you can serve that with the command `serve`:
<div class="termy">
```console
// Use the command "serve" after running "build-all"
$ python ./scripts/docs.py serve
Warning: this is a very simple server. For development, use mkdocs serve instead.
This is here only to preview a site with translations already built.
Make sure you run the build-all command first.
Serving at: http://127.0.0.1:8008
```
</div>
#### Translation specific tips and guidelines
* Translate only the Markdown documents (`.md`). Do not translate the code examples at `./docs_src`.
* In code blocks within the Markdown document, translate comments (`# a comment`), but leave the rest unchanged.
* Do not change anything enclosed in "``" (inline code).
* In lines starting with `///` translate only the text part after `|`. Leave the rest unchanged.
* You can translate info boxes like `/// warning` with for example `/// warning | Achtung`. But do not change the word immediately after the `///`, it determines the color of the info box.
* Do not change the paths in links to images, code files, Markdown documents.
* However, when a Markdown document is translated, the `#hash-parts` in links to its headings may change. Update these links if possible.
* Search for such links in the translated document using the regex `#[^# ]`.
* Search in all documents already translated into your language for `your-translated-document.md`. For example VS Code has an option "Edit" -> "Find in Files".
* When translating a document, do not "pre-translate" `#hash-parts` that link to headings in untranslated documents.
You have amazing tools at hand, use them wisely to help effectively.

View File

@@ -203,3 +203,8 @@ Inspired by Termynal's CSS tricks with modifications
-webkit-box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930;
box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930;
}
.md-typeset dfn {
border-bottom: .05rem dotted var(--md-default-fg-color--light);
cursor: help;
}

View File

@@ -14,7 +14,7 @@ In a hurry and already know this stuff? Jump to the [`Dockerfile` below 👇](#b
<summary>Dockerfile Preview 👀</summary>
```Dockerfile
FROM python:3.9
FROM python:3.14
WORKDIR /code
@@ -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}
```
@@ -168,7 +166,7 @@ Now in the same project directory create a file `Dockerfile` with:
```{ .dockerfile .annotate }
# (1)!
FROM python:3.9
FROM python:3.14
# (2)!
WORKDIR /code
@@ -392,7 +390,7 @@ If your FastAPI is a single file, for example, `main.py` without an `./app` dire
Then you would just have to change the corresponding paths to copy the file inside the `Dockerfile`:
```{ .dockerfile .annotate hl_lines="10 13" }
FROM python:3.9
FROM python:3.14
WORKDIR /code
@@ -456,7 +454,7 @@ Without using containers, making applications run on startup and with restarts c
## Replication - Number of Processes { #replication-number-of-processes }
If you have a <abbr title="A group of machines that are configured to be connected and work together in some way.">cluster</abbr> of machines with **Kubernetes**, Docker Swarm Mode, Nomad, or another similar complex system to manage distributed containers on multiple machines, then you will probably want to **handle replication** at the **cluster level** instead of using a **process manager** (like Uvicorn with workers) in each container.
If you have a <dfn title="A group of machines that are configured to be connected and work together in some way.">cluster</dfn> of machines with **Kubernetes**, Docker Swarm Mode, Nomad, or another similar complex system to manage distributed containers on multiple machines, then you will probably want to **handle replication** at the **cluster level** instead of using a **process manager** (like Uvicorn with workers) in each container.
One of those distributed container management systems like Kubernetes normally has some integrated way of handling **replication of containers** while still supporting **load balancing** for the incoming requests. All at the **cluster level**.
@@ -501,7 +499,7 @@ Of course, there are **special cases** where you could want to have **a containe
In those cases, you can use the `--workers` command line option to set the number of workers that you want to run:
```{ .dockerfile .annotate }
FROM python:3.9
FROM python:3.14
WORKDIR /code

View File

@@ -65,7 +65,7 @@ Here's an example of how an HTTPS API could look like, step by step, paying atte
It would probably all start by you **acquiring** some **domain name**. Then, you would configure it in a DNS server (possibly your same cloud provider).
You would probably get a cloud server (a virtual machine) or something similar, and it would have a <abbr title="That doesn't change">fixed</abbr> **public IP address**.
You would probably get a cloud server (a virtual machine) or something similar, and it would have a <dfn title="Doesn't change over time. Not dynamic.">fixed</dfn> **public IP address**.
In the DNS server(s) you would configure a record (an "`A record`") to point **your domain** to the public **IP address of your server**.

View File

@@ -196,31 +196,11 @@ They have contributed source code, documentation, etc. 📦
There are hundreds of other contributors, you can see them all in the <a href="https://github.com/fastapi/fastapi/graphs/contributors" class="external-link" target="_blank">FastAPI GitHub Contributors page</a>. 👷
## Top Translators
These are the **Top Translators**. 🌐
These users have created the most Pull Requests with [translations to other languages](contributing.md#translations){.internal-link target=_blank} that have been *merged*.
<div class="user-list user-list-center">
{% for user in (translators.values() | list)[:50] %}
{% if user.login not in skip_users %}
<div class="user"><a href="{{ user.url }}" target="_blank"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Translations: {{ user.count }}</div></div>
{% endif %}
{% endfor %}
</div>
## Top Translation Reviewers
These users are the **Top Translation Reviewers**. 🕵️
I only speak a few languages (and not very well 😅). So, the reviewers are the ones that have the [**power to approve translations**](contributing.md#translations){.internal-link target=_blank} of the documentation. Without them, there wouldn't be documentation in several other languages.
Translation reviewers have the [**power to approve translations**](contributing.md#translations){.internal-link target=_blank} of the documentation. Without them, there wouldn't be documentation in several other languages.
<div class="user-list user-list-center">
{% for user in (translation_reviewers.values() | list)[:50] %}

View File

@@ -6,7 +6,7 @@
### Based on open standards { #based-on-open-standards }
* <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a> for API creation, including declarations of <abbr title="also known as: endpoints, routes">path</abbr> <abbr title="also known as HTTP methods, as POST, GET, PUT, DELETE">operations</abbr>, parameters, request bodies, security, etc.
* <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a> for API creation, including declarations of <dfn title="also known as: endpoints, routes">path</dfn> <dfn title="also known as HTTP methods, as POST, GET, PUT, DELETE">operations</dfn>, parameters, request bodies, security, etc.
* Automatic data model documentation with <a href="https://json-schema.org/" class="external-link" target="_blank"><strong>JSON Schema</strong></a> (as OpenAPI itself is based on JSON Schema).
* Designed around these standards, after a meticulous study. Instead of an afterthought layer on top.
* This also allows using automatic **client code generation** in many languages.
@@ -136,7 +136,7 @@ All built as reusable tools and components that are easy to integrate with your
### Dependency Injection { #dependency-injection }
FastAPI includes an extremely easy to use, but extremely powerful <abbr title='also known as "components", "resources", "services", "providers"'><strong>Dependency Injection</strong></abbr> system.
FastAPI includes an extremely easy to use, but extremely powerful <dfn title='also known as "components", "resources", "services", "providers"'><strong>Dependency Injection</strong></dfn> system.
* Even dependencies can have dependencies, creating a hierarchy or **"graph" of dependencies**.
* All **automatically handled** by the framework.
@@ -153,8 +153,8 @@ Any integration is designed to be so simple to use (with dependencies) that you
### Tested { #tested }
* 100% <abbr title="The amount of code that is automatically tested">test coverage</abbr>.
* 100% <abbr title="Python type annotations, with this your editor and external tools can give you better support">type annotated</abbr> code base.
* 100% <dfn title="The amount of code that is automatically tested">test coverage</dfn>.
* 100% <dfn title="Python type annotations, with this your editor and external tools can give you better support">type annotated</dfn> code base.
* Used in production applications.
## Starlette features { #starlette-features }
@@ -190,7 +190,7 @@ With **FastAPI** you get all of **Pydantic**'s features (as FastAPI is based on
* **No brainfuck**:
* No new schema definition micro-language to learn.
* If you know Python types you know how to use Pydantic.
* Plays nicely with your **<abbr title="Integrated Development Environment: similar to a code editor">IDE</abbr>/<abbr title="A program that checks for code errors">linter</abbr>/brain**:
* Plays nicely with your **<abbr title="Integrated Development Environment: similar to a code editor">IDE</abbr>/<dfn title="A program that checks for code errors">linter</dfn>/brain**:
* Because pydantic data structures are just instances of classes you define; auto-completion, linting, mypy and your intuition should all work properly with your validated data.
* Validate **complex structures**:
* Use of hierarchical Pydantic models, Python `typing`s `List` and `Dict`, etc.

View File

@@ -8,7 +8,7 @@ But if for some reason your clients depend on the old behavior, you can revert t
For example, you can create a subclass of `HTTPBearer` that returns a `403 Forbidden` error instead of the default `401 Unauthorized` error:
{* ../../docs_src/authentication_error_status_code/tutorial001_an_py39.py hl[9:13] *}
{* ../../docs_src/authentication_error_status_code/tutorial001_an_py310.py hl[9:13] *}
/// tip

View File

@@ -29,7 +29,7 @@ You can easily use the same Pydantic settings to configure your generated OpenAP
For example:
{* ../../docs_src/conditional_openapi/tutorial001_py39.py hl[6,11] *}
{* ../../docs_src/conditional_openapi/tutorial001_py310.py hl[6,11] *}
Here we declare the setting `openapi_url` with the same default of `"/openapi.json"`.

View File

@@ -18,7 +18,7 @@ Without changing the settings, syntax highlighting is enabled by default:
But you can disable it by setting `syntaxHighlight` to `False`:
{* ../../docs_src/configure_swagger_ui/tutorial001_py39.py hl[3] *}
{* ../../docs_src/configure_swagger_ui/tutorial001_py310.py hl[3] *}
...and then Swagger UI won't show the syntax highlighting anymore:
@@ -28,7 +28,7 @@ But you can disable it by setting `syntaxHighlight` to `False`:
The same way you could set the syntax highlighting theme with the key `"syntaxHighlight.theme"` (notice that it has a dot in the middle):
{* ../../docs_src/configure_swagger_ui/tutorial002_py39.py hl[3] *}
{* ../../docs_src/configure_swagger_ui/tutorial002_py310.py hl[3] *}
That configuration would change the syntax highlighting color theme:
@@ -46,7 +46,7 @@ You can override any of them by setting a different value in the argument `swagg
For example, to disable `deepLinking` you could pass these settings to `swagger_ui_parameters`:
{* ../../docs_src/configure_swagger_ui/tutorial003_py39.py hl[3] *}
{* ../../docs_src/configure_swagger_ui/tutorial003_py310.py hl[3] *}
## Other Swagger UI Parameters { #other-swagger-ui-parameters }

View File

@@ -18,7 +18,7 @@ The first step is to disable the automatic docs, as by default, those use the de
To disable them, set their URLs to `None` when creating your `FastAPI` app:
{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[8] *}
{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[8] *}
### Include the custom docs { #include-the-custom-docs }
@@ -34,7 +34,7 @@ You can reuse FastAPI's internal functions to create the HTML pages for the docs
And similarly for ReDoc...
{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[2:6,11:19,22:24,27:33] *}
{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[2:6,11:19,22:24,27:33] *}
/// tip
@@ -50,7 +50,7 @@ Swagger UI will handle it behind the scenes for you, but it needs this "redirect
Now, to be able to test that everything works, create a *path operation*:
{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[36:38] *}
{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[36:38] *}
### Test it { #test-it }
@@ -118,7 +118,7 @@ After that, your file structure could look like:
* Import `StaticFiles`.
* "Mount" a `StaticFiles()` instance in a specific path.
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[7,11] *}
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[7,11] *}
### Test the static files { #test-the-static-files }
@@ -144,7 +144,7 @@ The same as when using a custom CDN, the first step is to disable the automatic
To disable them, set their URLs to `None` when creating your `FastAPI` app:
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[9] *}
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[9] *}
### Include the custom docs for static files { #include-the-custom-docs-for-static-files }
@@ -160,7 +160,7 @@ Again, you can reuse FastAPI's internal functions to create the HTML pages for t
And similarly for ReDoc...
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[2:6,14:22,25:27,30:36] *}
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[2:6,14:22,25:27,30:36] *}
/// tip
@@ -176,7 +176,7 @@ Swagger UI will handle it behind the scenes for you, but it needs this "redirect
Now, to be able to test that everything works, create a *path operation*:
{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[39:41] *}
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[39:41] *}
### Test Static Files UI { #test-static-files-ui }

View File

@@ -43,19 +43,19 @@ For example, let's add <a href="https://github.com/Rebilly/ReDoc/blob/master/doc
First, write all your **FastAPI** application as normally:
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[1,4,7:9] *}
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[1,4,7:9] *}
### Generate the OpenAPI schema { #generate-the-openapi-schema }
Then, use the same utility function to generate the OpenAPI schema, inside a `custom_openapi()` function:
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[2,15:21] *}
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[2,15:21] *}
### Modify the OpenAPI schema { #modify-the-openapi-schema }
Now you can add the ReDoc extension, adding a custom `x-logo` to the `info` "object" in the OpenAPI schema:
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[22:24] *}
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[22:24] *}
### Cache the OpenAPI schema { #cache-the-openapi-schema }
@@ -65,13 +65,13 @@ That way, your application won't have to generate the schema every time a user o
It will be generated only once, and then the same cached schema will be used for the next requests.
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[13:14,25:26] *}
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[13:14,25:26] *}
### Override the method { #override-the-method }
Now you can replace the `.openapi()` method with your new function.
{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[29] *}
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[29] *}
### Check it { #check-it }

View File

@@ -35,7 +35,7 @@ Depending on your use case, you might prefer to use a different library, but if
Here's a small preview of how you could integrate Strawberry with FastAPI:
{* ../../docs_src/graphql_/tutorial001_py39.py hl[3,22,25] *}
{* ../../docs_src/graphql_/tutorial001_py310.py hl[3,22,25] *}
You can learn more about Strawberry in the <a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry documentation</a>.

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@@ -40,7 +40,7 @@ The key features are:
* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
* **Fast to code**: Increase the speed to develop features by about 200% to 300%. *
* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. *
* **Intuitive**: Great editor support. <abbr title="also known as auto-complete, autocompletion, IntelliSense">Completion</abbr> everywhere. Less time debugging.
* **Intuitive**: Great editor support. <dfn title="also known as auto-complete, autocompletion, IntelliSense">Completion</dfn> everywhere. Less time debugging.
* **Easy**: Designed to be easy to use and learn. Less time reading docs.
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
* **Robust**: Get production-ready code. With automatic interactive documentation.
@@ -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}
@@ -374,7 +368,7 @@ item: Item
* Validation of data:
* Automatic and clear errors when the data is invalid.
* Validation even for deeply nested JSON objects.
* <abbr title="also known as: serialization, parsing, marshalling">Conversion</abbr> of input data: coming from the network to Python data and types. Reading from:
* <dfn title="also known as: serialization, parsing, marshalling">Conversion</dfn> of input data: coming from the network to Python data and types. Reading from:
* JSON.
* Path parameters.
* Query parameters.
@@ -382,7 +376,7 @@ item: Item
* Headers.
* Forms.
* Files.
* <abbr title="also known as: serialization, parsing, marshalling">Conversion</abbr> of output data: converting from Python data and types to network data (as JSON):
* <dfn title="also known as: serialization, parsing, marshalling">Conversion</dfn> of output data: converting from Python data and types to network data (as JSON):
* Convert Python types (`str`, `int`, `float`, `bool`, `list`, etc).
* `datetime` objects.
* `UUID` objects.
@@ -445,7 +439,7 @@ For a more complete example including more features, see the <a href="https://fa
* Declaration of **parameters** from other different places as: **headers**, **cookies**, **form fields** and **files**.
* How to set **validation constraints** as `maximum_length` or `regex`.
* A very powerful and easy to use **<abbr title="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** system.
* A very powerful and easy to use **<dfn title="also known as components, resources, providers, services, injectables">Dependency Injection</dfn>** system.
* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth.
* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic).
* **GraphQL** integration with <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> and other libraries.
@@ -530,7 +524,7 @@ Used by Starlette:
* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - Required if you want to use the `TestClient`.
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`.
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - Required if you want to support form <dfn title="converting the string that comes from an HTTP request into Python data">"parsing"</dfn>, with `request.form()`.
Used by FastAPI:

View File

@@ -81,8 +81,14 @@ function setupTermynal() {
}
}
saveBuffer();
const inputCommands = useLines
.filter(line => line.type === "input")
.map(line => line.value)
.join("\n");
node.textContent = inputCommands;
const div = document.createElement("div");
node.replaceWith(div);
node.style.display = "none";
node.after(div);
const termynal = new Termynal(div, {
lineData: useLines,
noInit: true,

View File

@@ -74,7 +74,7 @@ Make sure you use a supported label from the <a href="https://github.com/tiangol
* `refactor`: Refactors
* This is normally for changes to the internal code that don't change the behavior. Normally it improves maintainability, or enables future features, etc.
* `upgrade`: Upgrades
* This is for upgrades to direct dependencies from the project, or extra optional dependencies, normally in `pyproject.toml`. So, things that would affect final users, they would end up receiving the upgrade in their code base once they update. But this is not for upgrades to internal dependencies used for development, testing, docs, etc. Those internal dependencies, normally in `requirements.txt` files or GitHub Action versions should be marked as `internal`, not `upgrade`.
* This is for upgrades to direct dependencies from the project, or extra optional dependencies, normally in `pyproject.toml`. So, things that would affect final users, they would end up receiving the upgrade in their code base once they update. But this is not for upgrades to internal dependencies used for development, testing, docs, etc. Those internal dependencies or GitHub Action versions should be marked as `internal`, not `upgrade`.
* `docs`: Docs
* Changes in docs. This includes updating the docs, fixing typos. But it doesn't include changes to translations.
* You can normally quickly detect it by going to the "Files changed" tab in the PR and checking if the updated file(s) starts with `docs/en/docs`. The original version of the docs is always in English, so in `docs/en/docs`.
@@ -106,135 +106,25 @@ This way, we can notice when there are new translations ready, because they have
## Merge Translation PRs
For Spanish, as I'm a native speaker and it's a language close to me, I will give it a final review myself and in most cases tweak the PR a bit before merging it.
Translations are generated automatically with LLMs and scripts.
For the other languages, confirm that:
There's one GitHub Action that can be manually run to add or update translations for a language: <a href="https://github.com/fastapi/fastapi/actions/workflows/translate.yml" class="external-link" target="_blank">`translate.yml`</a>.
* The title is correct following the instructions above.
For these language translation PRs, confirm that:
* The PR was automated (authored by @tiangolo), not made by another user.
* It has the labels `lang-all` and `lang-{lang code}`.
* The PR changes only one Markdown file adding a translation.
* Or in some cases, at most two files, if they are small, for the same language, and people reviewed them.
* If it's the first translation for that language, it will have additional `mkdocs.yml` files, for those cases follow the instructions below.
* The PR doesn't add any additional or extraneous files.
* The translation seems to have a similar structure as the original English file.
* The translation doesn't seem to change the original content, for example with obvious additional documentation sections.
* The translation doesn't use different Markdown structures, for example adding HTML tags when the original didn't have them.
* The "admonition" sections, like `tip`, `info`, etc. are not changed or translated. For example:
```
/// tip
This is a tip.
///
```
looks like this:
/// tip
This is a tip.
///
...it could be translated as:
```
/// tip
Esto es un consejo.
///
```
...but needs to keep the exact `tip` keyword. If it was translated to `consejo`, like:
```
/// consejo
Esto es un consejo.
///
```
it would change the style to the default one, it would look like:
/// consejo
Esto es un consejo.
///
Those don't have to be translated, but if they are, they need to be written as:
```
/// tip | consejo
Esto es un consejo.
///
```
Which looks like:
/// tip | consejo
Esto es un consejo.
///
## First Translation PR
When there's a first translation for a language, it will have a `docs/{lang code}/docs/index.md` translated file and a `docs/{lang code}/mkdocs.yml`.
For example, for Bosnian, it would be:
* `docs/bs/docs/index.md`
* `docs/bs/mkdocs.yml`
The `mkdocs.yml` file will have only the following content:
```YAML
INHERIT: ../en/mkdocs.yml
```
The language code would normally be in the <a href="https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes" class="external-link" target="_blank">ISO 639-1 list of language codes</a>.
In any case, the language code should be in the file <a href="https://github.com/fastapi/fastapi/blob/master/docs/language_names.yml" class="external-link" target="_blank">docs/language_names.yml</a>.
There won't be yet a label for the language code, for example, if it was Bosnian, there wouldn't be a `lang-bs`. Before creating the label and adding it to the PR, create the GitHub Discussion:
* Go to the <a href="https://github.com/fastapi/fastapi/discussions/categories/translations" class="external-link" target="_blank">Translations GitHub Discussions</a>
* Create a new discussion with the title `Bosnian Translations` (or the language name in English)
* A description of:
```Markdown
## Bosnian translations
This is the issue to track translations of the docs to Bosnian. 🚀
Here are the [PRs to review with the label `lang-bs`](https://github.com/fastapi/fastapi/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc+label%3Alang-bs+label%3A%22awaiting-review%22). 🤓
```
Update "Bosnian" with the new language.
And update the search link to point to the new language label that will be created, like `lang-bs`.
Create and add the label to that new Discussion just created, like `lang-bs`.
Then go back to the PR, and add the label, like `lang-bs`, and `lang-all` and `awaiting-review`.
Now the GitHub action will automatically detect the label `lang-bs` and will post in that Discussion that this PR is waiting to be reviewed.
* If the PR is approved by at least one native speaker, you can merge it.
## Review PRs
If a PR doesn't explain what it does or why, ask for more information.
* If a PR doesn't explain what it does or why, if it seems like it could be useful, ask for more information. Otherwise, feel free to close it.
A PR should have a specific use case that it is solving.
* If a PR seems to be spam, meaningless, only to change statistics (to appear as "contributor") or similar, you can simply mark it as `invalid`, and it will be automatically closed.
* If a PR seems to be AI generated, and seems like reviewing it would take more time from you than the time it took to write the prompt, mark it as `maybe-ai`, and it will be automatically closed.
* A PR should have a specific use case that it is solving.
* If the PR is for a feature, it should have docs.
* Unless it's a feature we want to discourage, like support for a corner case that we don't want users to use.
@@ -254,27 +144,12 @@ Every month, a GitHub Action updates the FastAPI People data. Those PRs look lik
If the tests are passing, you can merge it right away.
## External Links PRs
When people add external links they edit this file <a href="https://github.com/fastapi/fastapi/blob/master/docs/en/data/external_links.yml" class="external-link" target="_blank">external_links.yml</a>.
* Make sure the new link is in the correct category (e.g. "Podcasts") and language (e.g. "Japanese").
* A new link should be at the top of its list.
* The link URL should work (it should not return a 404).
* The content of the link should be about FastAPI.
* The new addition should have these fields:
* `author`: The name of the author.
* `link`: The URL with the content.
* `title`: The title of the link (the title of the article, podcast, etc).
After checking all these things and ensuring the PR has the right labels, you can merge it.
## Dependabot PRs
Dependabot will create PRs to update dependencies for several things, and those PRs all look similar, but some are way more delicate than others.
* If the PR is for a direct dependency, so, Dependabot is modifying `pyproject.toml`, **don't merge it**. 😱 Let me check it first. There's a good chance that some additional tweaks or updates are needed.
* If the PR updates one of the internal dependencies, for example it's modifying `requirements.txt` files, or GitHub Action versions, if the tests are passing, the release notes (shown in a summary in the PR) don't show any obvious potential breaking change, you can merge it. 😎
* If the PR is for a direct dependency, so, Dependabot is modifying `pyproject.toml` in the main dependencies, **don't merge it**. 😱 Let me check it first. There's a good chance that some additional tweaks or updates are needed.
* If the PR updates one of the internal dependencies, for example the group `dev` in `pyproject.toml`, or GitHub Action versions, if the tests are passing, the release notes (shown in a summary in the PR) don't show any obvious potential breaking change, you can merge it. 😎
## Mark GitHub Discussions Answers

View File

@@ -2,7 +2,7 @@
Python has support for optional "type hints" (also called "type annotations").
These **"type hints"** or annotations are a special syntax that allow declaring the <abbr title="for example: str, int, float, bool">type</abbr> of a variable.
These **"type hints"** or annotations are a special syntax that allow declaring the <dfn title="for example: str, int, float, bool">type</dfn> of a variable.
By declaring types for your variables, editors and tools can give you better support.
@@ -22,7 +22,7 @@ If you are a Python expert, and you already know everything about type hints, sk
Let's start with a simple example:
{* ../../docs_src/python_types/tutorial001_py39.py *}
{* ../../docs_src/python_types/tutorial001_py310.py *}
Calling this program outputs:
@@ -34,9 +34,9 @@ The function does the following:
* Takes a `first_name` and `last_name`.
* Converts the first letter of each one to upper case with `title()`.
* <abbr title="Puts them together, as one. With the contents of one after the other.">Concatenates</abbr> them with a space in the middle.
* <dfn title="Puts them together, as one. With the contents of one after the other.">Concatenates</dfn> them with a space in the middle.
{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *}
{* ../../docs_src/python_types/tutorial001_py310.py hl[2] *}
### Edit it { #edit-it }
@@ -78,7 +78,7 @@ That's it.
Those are the "type hints":
{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *}
{* ../../docs_src/python_types/tutorial002_py310.py hl[1] *}
That is not the same as declaring default values like would be with:
@@ -106,7 +106,7 @@ With that, you can scroll, seeing the options, until you find the one that "ring
Check this function, it already has type hints:
{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *}
{* ../../docs_src/python_types/tutorial003_py310.py hl[1] *}
Because the editor knows the types of the variables, you don't only get completion, you also get error checks:
@@ -114,7 +114,7 @@ Because the editor knows the types of the variables, you don't only get completi
Now you know that you have to fix it, convert `age` to a string with `str(age)`:
{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *}
{* ../../docs_src/python_types/tutorial004_py310.py hl[2] *}
## Declaring types { #declaring-types }
@@ -133,29 +133,32 @@ You can use, for example:
* `bool`
* `bytes`
{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *}
{* ../../docs_src/python_types/tutorial005_py310.py hl[1] *}
### Generic types with type parameters { #generic-types-with-type-parameters }
### `typing` module { #typing-module }
There are some data structures that can contain other values, like `dict`, `list`, `set` and `tuple`. And the internal values can have their own type too.
For some additional use cases, you might need to import some things from the standard library `typing` module, for example when you want to declare that something has "any type", you can use `Any` from `typing`:
These types that have internal types are called "**generic**" types. And it's possible to declare them, even with their internal types.
```python
from typing import Any
To declare those types and the internal types, you can use the standard Python module `typing`. It exists specifically to support these type hints.
#### Newer versions of Python { #newer-versions-of-python }
def some_function(data: Any):
print(data)
```
The syntax using `typing` is **compatible** with all versions, from Python 3.6 to the latest ones, including Python 3.9, Python 3.10, etc.
### Generic types { #generic-types }
As Python advances, **newer versions** come with improved support for these type annotations and in many cases you won't even need to import and use the `typing` module to declare the type annotations.
Some types can take "type parameters" in square brackets, to define their internal types, for example a "list of strings" would be declared `list[str]`.
If you can choose a more recent version of Python for your project, you will be able to take advantage of that extra simplicity.
These types that can take type parameters are called **Generic types** or **Generics**.
In all the docs there are examples compatible with each version of Python (when there's a difference).
You can use the same builtin types as generics (with square brackets and types inside):
For example "**Python 3.6+**" means it's compatible with Python 3.6 or above (including 3.7, 3.8, 3.9, 3.10, etc). And "**Python 3.9+**" means it's compatible with Python 3.9 or above (including 3.10, etc).
If you can use the **latest versions of Python**, use the examples for the latest version, those will have the **best and simplest syntax**, for example, "**Python 3.10+**".
* `list`
* `tuple`
* `set`
* `dict`
#### List { #list }
@@ -167,7 +170,7 @@ As the type, put `list`.
As the list is a type that contains some internal types, you put them in square brackets:
{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *}
{* ../../docs_src/python_types/tutorial006_py310.py hl[1] *}
/// info
@@ -193,7 +196,7 @@ And still, the editor knows it is a `str`, and provides support for that.
You would do the same to declare `tuple`s and `set`s:
{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *}
{* ../../docs_src/python_types/tutorial007_py310.py hl[1] *}
This means:
@@ -208,7 +211,7 @@ The first type parameter is for the keys of the `dict`.
The second type parameter is for the values of the `dict`:
{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *}
{* ../../docs_src/python_types/tutorial008_py310.py hl[1] *}
This means:
@@ -220,44 +223,20 @@ This means:
You can declare that a variable can be any of **several types**, for example, an `int` or a `str`.
In Python 3.6 and above (including Python 3.10) you can use the `Union` type from `typing` and put inside the square brackets the possible types to accept.
To define it you use the <dfn title='also called "bitwise or operator", but that meaning is not relevant here'>vertical bar (`|`)</dfn> to separate both types.
In Python 3.10 there's also a **new syntax** where you can put the possible types separated by a <abbr title='also called "bitwise or operator", but that meaning is not relevant here'>vertical bar (`|`)</abbr>.
//// tab | Python 3.10+
This is called a "union", because the variable can be anything in the union of those two sets of types.
```Python hl_lines="1"
{!> ../../docs_src/python_types/tutorial008b_py310.py!}
```
////
//// tab | Python 3.9+
```Python hl_lines="1 4"
{!> ../../docs_src/python_types/tutorial008b_py39.py!}
```
////
In both cases this means that `item` could be an `int` or a `str`.
This means that `item` could be an `int` or a `str`.
#### Possibly `None` { #possibly-none }
You can declare that a value could have a type, like `str`, but that it could also be `None`.
In Python 3.6 and above (including Python 3.10) you can declare it by importing and using `Optional` from the `typing` module.
```Python hl_lines="1 4"
{!../../docs_src/python_types/tutorial009_py39.py!}
```
Using `Optional[str]` instead of just `str` will let the editor help you detect errors where you could be assuming that a value is always a `str`, when it could actually be `None` too.
`Optional[Something]` is actually a shortcut for `Union[Something, None]`, they are equivalent.
This also means that in Python 3.10, you can use `Something | None`:
//// tab | Python 3.10+
```Python hl_lines="1"
@@ -266,96 +245,7 @@ This also means that in Python 3.10, you can use `Something | None`:
////
//// tab | Python 3.9+
```Python hl_lines="1 4"
{!> ../../docs_src/python_types/tutorial009_py39.py!}
```
////
//// tab | Python 3.9+ alternative
```Python hl_lines="1 4"
{!> ../../docs_src/python_types/tutorial009b_py39.py!}
```
////
#### Using `Union` or `Optional` { #using-union-or-optional }
If you are using a Python version below 3.10, here's a tip from my very **subjective** point of view:
* 🚨 Avoid using `Optional[SomeType]`
* Instead ✨ **use `Union[SomeType, None]`** ✨.
Both are equivalent and underneath they are the same, but I would recommend `Union` instead of `Optional` because the word "**optional**" would seem to imply that the value is optional, and it actually means "it can be `None`", even if it's not optional and is still required.
I think `Union[SomeType, None]` is more explicit about what it means.
It's just about the words and names. But those words can affect how you and your teammates think about the code.
As an example, let's take this function:
{* ../../docs_src/python_types/tutorial009c_py39.py hl[1,4] *}
The parameter `name` is defined as `Optional[str]`, but it is **not optional**, you cannot call the function without the parameter:
```Python
say_hi() # Oh, no, this throws an error! 😱
```
The `name` parameter is **still required** (not *optional*) because it doesn't have a default value. Still, `name` accepts `None` as the value:
```Python
say_hi(name=None) # This works, None is valid 🎉
```
The good news is, once you are on Python 3.10 you won't have to worry about that, as you will be able to simply use `|` to define unions of types:
{* ../../docs_src/python_types/tutorial009c_py310.py hl[1,4] *}
And then you won't have to worry about names like `Optional` and `Union`. 😎
#### Generic types { #generic-types }
These types that take type parameters in square brackets are called **Generic types** or **Generics**, for example:
//// tab | Python 3.10+
You can use the same builtin types as generics (with square brackets and types inside):
* `list`
* `tuple`
* `set`
* `dict`
And the same as with previous Python versions, from the `typing` module:
* `Union`
* `Optional`
* ...and others.
In Python 3.10, as an alternative to using the generics `Union` and `Optional`, you can use the <abbr title='also called "bitwise or operator", but that meaning is not relevant here'>vertical bar (`|`)</abbr> to declare unions of types, that's a lot better and simpler.
////
//// tab | Python 3.9+
You can use the same builtin types as generics (with square brackets and types inside):
* `list`
* `tuple`
* `set`
* `dict`
And generics from the `typing` module:
* `Union`
* `Optional`
* ...and others.
////
Using `str | None` instead of just `str` will let the editor help you detect errors where you could be assuming that a value is always a `str`, when it could actually be `None` too.
### Classes as types { #classes-as-types }
@@ -363,11 +253,11 @@ You can also declare a class as the type of a variable.
Let's say you have a class `Person`, with a name:
{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *}
{* ../../docs_src/python_types/tutorial010_py310.py hl[1:3] *}
Then you can declare a variable to be of type `Person`:
{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *}
{* ../../docs_src/python_types/tutorial010_py310.py hl[6] *}
And then, again, you get all the editor support:
@@ -403,19 +293,13 @@ To learn more about <a href="https://docs.pydantic.dev/" class="external-link" t
You will see a lot more of all this in practice in the [Tutorial - User Guide](tutorial/index.md){.internal-link target=_blank}.
/// tip
Pydantic has a special behavior when you use `Optional` or `Union[Something, None]` without a default value, you can read more about it in the Pydantic docs about <a href="https://docs.pydantic.dev/2.3/usage/models/#required-fields" class="external-link" target="_blank">Required Optional fields</a>.
///
## Type Hints with Metadata Annotations { #type-hints-with-metadata-annotations }
Python also has a feature that allows putting **additional <abbr title="Data about the data, in this case, information about the type, e.g. a description.">metadata</abbr>** in these type hints using `Annotated`.
Python also has a feature that allows putting **additional <dfn title="Data about the data, in this case, information about the type, e.g. a description.">metadata</dfn>** in these type hints using `Annotated`.
Since Python 3.9, `Annotated` is a part of the standard library, so you can import it from `typing`.
You can import `Annotated` from `typing`.
{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *}
{* ../../docs_src/python_types/tutorial013_py310.py hl[1,4] *}
Python itself doesn't do anything with this `Annotated`. And for editors and other tools, the type is still `str`.

View File

@@ -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
```

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -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.

View File

@@ -7,14 +7,234 @@ hide:
## Latest Changes
### Breaking Changes
* Drop support for Python 3.9. PR [#14897](https://github.com/fastapi/fastapi/pull/14897) by [@tiangolo](https://github.com/tiangolo).
### Refactors
* 🎨 Update internal types for Python 3.10. PR [#14898](https://github.com/fastapi/fastapi/pull/14898) by [@tiangolo](https://github.com/tiangolo).
## 0.128.8
### Docs
* 📝 Fix grammar in `docs/en/docs/tutorial/first-steps.md`. PR [#14708](https://github.com/fastapi/fastapi/pull/14708) by [@SanjanaS10](https://github.com/SanjanaS10).
### Internal
* 🔨 Tweak PDM hook script. PR [#14895](https://github.com/fastapi/fastapi/pull/14895) by [@tiangolo](https://github.com/tiangolo).
* ♻️ Update build setup for `fastapi-slim`, deprecate it, and make it only depend on `fastapi`. PR [#14894](https://github.com/fastapi/fastapi/pull/14894) by [@tiangolo](https://github.com/tiangolo).
## 0.128.7
### Features
* ✨ Show a clear error on attempt to include router into itself. PR [#14258](https://github.com/fastapi/fastapi/pull/14258) by [@JavierSanchezCastro](https://github.com/JavierSanchezCastro).
* ✨ Replace `dict` by `Mapping` on `HTTPException.headers`. PR [#12997](https://github.com/fastapi/fastapi/pull/12997) by [@rijenkii](https://github.com/rijenkii).
### Refactors
* ♻️ Simplify reading files in memory, do it sequentially instead of (fake) parallel. PR [#14884](https://github.com/fastapi/fastapi/pull/14884) by [@tiangolo](https://github.com/tiangolo).
### Docs
* 📝 Use `dfn` tag for definitions instead of `abbr` in docs. PR [#14744](https://github.com/fastapi/fastapi/pull/14744) by [@YuriiMotov](https://github.com/YuriiMotov).
### Internal
* ✅ Tweak comment in test to reference PR. PR [#14885](https://github.com/fastapi/fastapi/pull/14885) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Update LLM-prompt for `abbr` and `dfn` tags. PR [#14747](https://github.com/fastapi/fastapi/pull/14747) by [@YuriiMotov](https://github.com/YuriiMotov).
* ✅ Test order for the submitted byte Files. PR [#14828](https://github.com/fastapi/fastapi/pull/14828) by [@valentinDruzhinin](https://github.com/valentinDruzhinin).
* 🔧 Configure `test` workflow to run tests with `inline-snapshot=review`. PR [#14876](https://github.com/fastapi/fastapi/pull/14876) by [@YuriiMotov](https://github.com/YuriiMotov).
## 0.128.6
### Fixes
* 🐛 Fix `on_startup` and `on_shutdown` parameters of `APIRouter`. PR [#14873](https://github.com/fastapi/fastapi/pull/14873) by [@YuriiMotov](https://github.com/YuriiMotov).
### Translations
* 🌐 Update translations for zh (update-outdated). PR [#14843](https://github.com/fastapi/fastapi/pull/14843) by [@tiangolo](https://github.com/tiangolo).
### Internal
* ✅ Fix parameterized tests with snapshots. PR [#14875](https://github.com/fastapi/fastapi/pull/14875) by [@YuriiMotov](https://github.com/YuriiMotov).
## 0.128.5
### Refactors
* ♻️ Refactor and simplify Pydantic v2 (and v1) compatibility internal utils. PR [#14862](https://github.com/fastapi/fastapi/pull/14862) by [@tiangolo](https://github.com/tiangolo).
### Internal
* ✅ Add inline snapshot tests for OpenAPI before changes from Pydantic v2. PR [#14864](https://github.com/fastapi/fastapi/pull/14864) by [@tiangolo](https://github.com/tiangolo).
## 0.128.4
### Refactors
* ♻️ Refactor internals, simplify Pydantic v2/v1 utils, `create_model_field`, better types for `lenient_issubclass`. PR [#14860](https://github.com/fastapi/fastapi/pull/14860) by [@tiangolo](https://github.com/tiangolo).
* ♻️ Simplify internals, remove Pydantic v1 only logic, no longer needed. PR [#14857](https://github.com/fastapi/fastapi/pull/14857) by [@tiangolo](https://github.com/tiangolo).
* ♻️ Refactor internals, cleanup unneeded Pydantic v1 specific logic. PR [#14856](https://github.com/fastapi/fastapi/pull/14856) by [@tiangolo](https://github.com/tiangolo).
### Translations
* 🌐 Update translations for fr (outdated pages). PR [#14839](https://github.com/fastapi/fastapi/pull/14839) by [@YuriiMotov](https://github.com/YuriiMotov).
* 🌐 Update translations for tr (outdated and missing). PR [#14838](https://github.com/fastapi/fastapi/pull/14838) by [@YuriiMotov](https://github.com/YuriiMotov).
### Internal
* ⬆️ Upgrade development dependencies. PR [#14854](https://github.com/fastapi/fastapi/pull/14854) by [@tiangolo](https://github.com/tiangolo).
## 0.128.3
### Refactors
* ♻️ Re-implement `on_event` in FastAPI for compatibility with the next Starlette, while keeping backwards compatibility. PR [#14851](https://github.com/fastapi/fastapi/pull/14851) by [@tiangolo](https://github.com/tiangolo).
### Upgrades
* ⬆️ Upgrade Starlette supported version range to `starlette>=0.40.0,<1.0.0`. PR [#14853](https://github.com/fastapi/fastapi/pull/14853) by [@tiangolo](https://github.com/tiangolo).
### Translations
* 🌐 Update translations for ru (update-outdated). PR [#14834](https://github.com/fastapi/fastapi/pull/14834) by [@tiangolo](https://github.com/tiangolo).
### Internal
* 👷 Run tests with Starlette from git. PR [#14849](https://github.com/fastapi/fastapi/pull/14849) by [@tiangolo](https://github.com/tiangolo).
* 👷 Run tests with lower bound uv sync, upgrade `fastapi[all]` minimum dependencies: `ujson >=5.8.0`, `orjson >=3.9.3`. PR [#14846](https://github.com/fastapi/fastapi/pull/14846) by [@tiangolo](https://github.com/tiangolo).
## 0.128.2
### Features
* ✨ Add support for PEP695 `TypeAliasType`. PR [#13920](https://github.com/fastapi/fastapi/pull/13920) by [@cstruct](https://github.com/cstruct).
* ✨ Allow `Response` type hint as dependency annotation. PR [#14794](https://github.com/fastapi/fastapi/pull/14794) by [@jonathan-fulton](https://github.com/jonathan-fulton).
### Fixes
* 🐛 Fix using `Json[list[str]]` type (issue #10997). PR [#14616](https://github.com/fastapi/fastapi/pull/14616) by [@mkanetsuna](https://github.com/mkanetsuna).
### Docs
* 📝 Update docs for translations. PR [#14830](https://github.com/fastapi/fastapi/pull/14830) by [@tiangolo](https://github.com/tiangolo).
* 📝 Fix duplicate word in `advanced-dependencies.md`. PR [#14815](https://github.com/fastapi/fastapi/pull/14815) by [@Rayyan-Oumlil](https://github.com/Rayyan-Oumlil).
### Translations
* 🌐 Enable Traditional Chinese translations. PR [#14842](https://github.com/fastapi/fastapi/pull/14842) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Enable French docs translations. PR [#14841](https://github.com/fastapi/fastapi/pull/14841) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for fr (translate-page). PR [#14837](https://github.com/fastapi/fastapi/pull/14837) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for de (update-outdated). PR [#14836](https://github.com/fastapi/fastapi/pull/14836) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for pt (update-outdated). PR [#14833](https://github.com/fastapi/fastapi/pull/14833) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for ko (update-outdated). PR [#14835](https://github.com/fastapi/fastapi/pull/14835) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for es (update-outdated). PR [#14832](https://github.com/fastapi/fastapi/pull/14832) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for tr (update-outdated). PR [#14831](https://github.com/fastapi/fastapi/pull/14831) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for tr (add-missing). PR [#14790](https://github.com/fastapi/fastapi/pull/14790) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for fr (update-outdated). PR [#14826](https://github.com/fastapi/fastapi/pull/14826) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for zh-hant (update-outdated). PR [#14825](https://github.com/fastapi/fastapi/pull/14825) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for uk (update-outdated). PR [#14822](https://github.com/fastapi/fastapi/pull/14822) by [@tiangolo](https://github.com/tiangolo).
* 🔨 Update docs and translations scripts, enable Turkish. PR [#14824](https://github.com/fastapi/fastapi/pull/14824) by [@tiangolo](https://github.com/tiangolo).
### Internal
* 🔨 Add max pages to translate to configs. PR [#14840](https://github.com/fastapi/fastapi/pull/14840) by [@tiangolo](https://github.com/tiangolo).
## 0.128.1
### 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
* 🐛 Update `ValidationError` schema to include `input` and `ctx`. PR [#14791](https://github.com/fastapi/fastapi/pull/14791) by [@jonathan-fulton](https://github.com/jonathan-fulton).
* 🐛 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).
### 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).
### Docs
* 📝 Update docs for contributing translations, simplify title. PR [#14817](https://github.com/fastapi/fastapi/pull/14817) by [@tiangolo](https://github.com/tiangolo).
* 📝 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).
* 📝 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).
* 📝 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).
* 📝 Update docs for management tasks. PR [#14705](https://github.com/fastapi/fastapi/pull/14705) by [@tiangolo](https://github.com/tiangolo).
* 📝 Update docs about managing translations. PR [#14704](https://github.com/fastapi/fastapi/pull/14704) by [@tiangolo](https://github.com/tiangolo).
* 📝 Update docs for contributing with translations. PR [#14701](https://github.com/fastapi/fastapi/pull/14701) by [@tiangolo](https://github.com/tiangolo).
* 📝 Specify language code for code block. PR [#14656](https://github.com/fastapi/fastapi/pull/14656) by [@YuriiMotov](https://github.com/YuriiMotov).
### Translations
* 🌐 Improve LLM prompt of `uk` documentation. PR [#14795](https://github.com/fastapi/fastapi/pull/14795) by [@roli2py](https://github.com/roli2py).
* 🌐 Update translations for ja (update-outdated). PR [#14588](https://github.com/fastapi/fastapi/pull/14588) by [@tiangolo](https://github.com/tiangolo).
* 🌐 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).
* 🌐 Update translations for de (update-outdated). PR [#14690](https://github.com/fastapi/fastapi/pull/14690) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update LLM prompt for Russian translations. PR [#14733](https://github.com/fastapi/fastapi/pull/14733) by [@YuriiMotov](https://github.com/YuriiMotov).
* 🌐 Update translations for ru (update-outdated). PR [#14693](https://github.com/fastapi/fastapi/pull/14693) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for pt (update-outdated). PR [#14724](https://github.com/fastapi/fastapi/pull/14724) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update Korean LLM prompt. PR [#14740](https://github.com/fastapi/fastapi/pull/14740) by [@hard-coders](https://github.com/hard-coders).
* 🌐 Improve LLM prompt for Turkish translations. PR [#14728](https://github.com/fastapi/fastapi/pull/14728) by [@Kadermiyanyedi](https://github.com/Kadermiyanyedi).
* 🌐 Update portuguese llm-prompt.md. PR [#14702](https://github.com/fastapi/fastapi/pull/14702) by [@ceb10n](https://github.com/ceb10n).
* 🌐 Update LLM prompt instructions file for French. PR [#14618](https://github.com/fastapi/fastapi/pull/14618) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for ko (add-missing). PR [#14699](https://github.com/fastapi/fastapi/pull/14699) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for ko (update-outdated). PR [#14589](https://github.com/fastapi/fastapi/pull/14589) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for uk (update-outdated). PR [#14587](https://github.com/fastapi/fastapi/pull/14587) by [@tiangolo](https://github.com/tiangolo).
* 🌐 Update translations for es (update-outdated). PR [#14686](https://github.com/fastapi/fastapi/pull/14686) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Add LLM prompt file for Turkish, generated from the existing translations. PR [#14547](https://github.com/fastapi/fastapi/pull/14547) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Add LLM prompt file for Traditional Chinese, generated from the existing translations. PR [#14550](https://github.com/fastapi/fastapi/pull/14550) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Add LLM prompt file for Simplified Chinese, generated from the existing translations. PR [#14549](https://github.com/fastapi/fastapi/pull/14549) by [@tiangolo](https://github.com/tiangolo).
### Internal
* ⬇️ Downgrade LLM translations model to GPT-5 to reduce mistakes. PR [#14823](https://github.com/fastapi/fastapi/pull/14823) by [@tiangolo](https://github.com/tiangolo).
* 🐛 Fix translation script commit in place. PR [#14818](https://github.com/fastapi/fastapi/pull/14818) by [@tiangolo](https://github.com/tiangolo).
* 🔨 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).
* ⬆ 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).
* ⬆ 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).
* 🔧 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).
* ⬆ Bump actions/cache from 4 to 5. PR [#14511](https://github.com/fastapi/fastapi/pull/14511) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump actions/upload-artifact from 5 to 6. PR [#14525](https://github.com/fastapi/fastapi/pull/14525) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump actions/download-artifact from 6 to 7. PR [#14526](https://github.com/fastapi/fastapi/pull/14526) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 👷 Tweak CI input names. PR [#14688](https://github.com/fastapi/fastapi/pull/14688) by [@tiangolo](https://github.com/tiangolo).
* 🔨 Refactor translation script to allow committing in place. PR [#14687](https://github.com/fastapi/fastapi/pull/14687) by [@tiangolo](https://github.com/tiangolo).
* 🐛 Fix translation script path. PR [#14685](https://github.com/fastapi/fastapi/pull/14685) by [@tiangolo](https://github.com/tiangolo).
* ✅ Enable tests in CI for scripts. PR [#14684](https://github.com/fastapi/fastapi/pull/14684) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Add pre-commit local script to fix language translations. PR [#14683](https://github.com/fastapi/fastapi/pull/14683) by [@tiangolo](https://github.com/tiangolo).
* ⬆️ Migrate to uv. PR [#14676](https://github.com/fastapi/fastapi/pull/14676) by [@DoctorJohn](https://github.com/DoctorJohn).
* 🔨 Add LLM translations tool fixer. PR [#14652](https://github.com/fastapi/fastapi/pull/14652) by [@YuriiMotov](https://github.com/YuriiMotov).
* 👥 Update FastAPI People - Sponsors. PR [#14626](https://github.com/fastapi/fastapi/pull/14626) by [@tiangolo](https://github.com/tiangolo).
* 👥 Update FastAPI GitHub topic repositories. PR [#14630](https://github.com/fastapi/fastapi/pull/14630) by [@tiangolo](https://github.com/tiangolo).
* 👥 Update FastAPI People - Contributors and Translators. PR [#14625](https://github.com/fastapi/fastapi/pull/14625) by [@tiangolo](https://github.com/tiangolo).
@@ -247,7 +467,7 @@ hide:
### Refactors
* 🔥 Remove dangling extra condiitonal no longer needed. PR [#14435](https://github.com/fastapi/fastapi/pull/14435) by [@tiangolo](https://github.com/tiangolo).
* 🔥 Remove dangling extra conditional no longer needed. PR [#14435](https://github.com/fastapi/fastapi/pull/14435) by [@tiangolo](https://github.com/tiangolo).
* ♻️ Refactor internals, update `is_coroutine` check to reuse internal supported variants (unwrap, check class). PR [#14434](https://github.com/fastapi/fastapi/pull/14434) by [@tiangolo](https://github.com/tiangolo).
### Translations
@@ -382,7 +602,7 @@ hide:
### Docs
* 📝 Upate docs for advanced dependencies with `yield`, noting the changes in 0.121.0, adding `scope`. PR [#14287](https://github.com/fastapi/fastapi/pull/14287) by [@tiangolo](https://github.com/tiangolo).
* 📝 Update docs for advanced dependencies with `yield`, noting the changes in 0.121.0, adding `scope`. PR [#14287](https://github.com/fastapi/fastapi/pull/14287) by [@tiangolo](https://github.com/tiangolo).
### Internal
@@ -2610,7 +2830,7 @@ Read more in the [advisory: Content-Type Header ReDoS](https://github.com/tiango
* 🌐 Add Japanese translation for `docs/ja/docs/tutorial/handling-errors.md`. PR [#1953](https://github.com/tiangolo/fastapi/pull/1953) by [@SwftAlpc](https://github.com/SwftAlpc).
* 🌐 Add Japanese translation for `docs/ja/docs/tutorial/response-status-code.md`. PR [#1942](https://github.com/tiangolo/fastapi/pull/1942) by [@SwftAlpc](https://github.com/SwftAlpc).
* 🌐 Add Japanese translation for `docs/ja/docs/tutorial/extra-models.md`. PR [#1941](https://github.com/tiangolo/fastapi/pull/1941) by [@SwftAlpc](https://github.com/SwftAlpc).
* 🌐 Add Japanese tranlsation for `docs/ja/docs/tutorial/schema-extra-example.md`. PR [#1931](https://github.com/tiangolo/fastapi/pull/1931) by [@SwftAlpc](https://github.com/SwftAlpc).
* 🌐 Add Japanese translation for `docs/ja/docs/tutorial/schema-extra-example.md`. PR [#1931](https://github.com/tiangolo/fastapi/pull/1931) by [@SwftAlpc](https://github.com/SwftAlpc).
* 🌐 Add Japanese translation for `docs/ja/docs/tutorial/body-nested-models.md`. PR [#1930](https://github.com/tiangolo/fastapi/pull/1930) by [@SwftAlpc](https://github.com/SwftAlpc).
* 🌐 Add Japanese translation for `docs/ja/docs/tutorial/body-fields.md`. PR [#1923](https://github.com/tiangolo/fastapi/pull/1923) by [@SwftAlpc](https://github.com/SwftAlpc).
* 🌐 Add German translation for `docs/de/docs/tutorial/index.md`. PR [#9502](https://github.com/tiangolo/fastapi/pull/9502) by [@fhabers21](https://github.com/fhabers21).
@@ -3986,7 +4206,7 @@ You hopefully updated to a supported version of Python a while ago. If you haven
### Fixes
* 🐛 Fix `RuntimeError` raised when `HTTPException` has a status code with no content. PR [#5365](https://github.com/tiangolo/fastapi/pull/5365) by [@iudeen](https://github.com/iudeen).
* 🐛 Fix empty reponse body when default `status_code` is empty but the a `Response` parameter with `response.status_code` is set. PR [#5360](https://github.com/tiangolo/fastapi/pull/5360) by [@tmeckel](https://github.com/tmeckel).
* 🐛 Fix empty response body when default `status_code` is empty but the a `Response` parameter with `response.status_code` is set. PR [#5360](https://github.com/tiangolo/fastapi/pull/5360) by [@tmeckel](https://github.com/tmeckel).
### Docs

View File

@@ -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)
///

View File

@@ -15,7 +15,7 @@ This includes, for example:
First, import `BackgroundTasks` and define a parameter in your *path operation function* with a type declaration of `BackgroundTasks`:
{* ../../docs_src/background_tasks/tutorial001_py39.py hl[1,13] *}
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[1,13] *}
**FastAPI** will create the object of type `BackgroundTasks` for you and pass it as that parameter.
@@ -31,13 +31,13 @@ In this case, the task function will write to a file (simulating sending an emai
And as the write operation doesn't use `async` and `await`, we define the function with normal `def`:
{* ../../docs_src/background_tasks/tutorial001_py39.py hl[6:9] *}
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[6:9] *}
## Add the background task { #add-the-background-task }
Inside of your *path operation function*, pass your task function to the *background tasks* object with the method `.add_task()`:
{* ../../docs_src/background_tasks/tutorial001_py39.py hl[14] *}
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[14] *}
`.add_task()` receives as arguments:

View File

@@ -56,7 +56,7 @@ from app.routers import items
The same file structure with comments:
```
```bash
.
├── app # "app" is a Python package
│   ├── __init__.py # this file makes "app" a "Python package"
@@ -85,7 +85,7 @@ You can create the *path operations* for that module using `APIRouter`.
You import it and create an "instance" the same way you would with the class `FastAPI`:
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[1,3] title["app/routers/users.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/routers/users.py hl[1,3] title["app/routers/users.py"] *}
### *Path operations* with `APIRouter` { #path-operations-with-apirouter }
@@ -93,7 +93,7 @@ And then you use it to declare your *path operations*.
Use it the same way you would use the `FastAPI` class:
{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
You can think of `APIRouter` as a "mini `FastAPI`" class.
@@ -117,7 +117,7 @@ So we put them in their own `dependencies` module (`app/dependencies.py`).
We will now use a simple dependency to read a custom `X-Token` header:
{* ../../docs_src/bigger_applications/app_an_py39/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
/// tip
@@ -149,7 +149,7 @@ We know all the *path operations* in this module have the same:
So, instead of adding all that to each *path operation*, we can add it to the `APIRouter`.
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
As the path of each *path operation* has to start with `/`, like in:
@@ -208,7 +208,7 @@ And we need to get the dependency function from the module `app.dependencies`, t
So we use a relative import with `..` for the dependencies:
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[3] title["app/routers/items.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[3] title["app/routers/items.py"] *}
#### How relative imports work { #how-relative-imports-work }
@@ -279,7 +279,7 @@ We are not adding the prefix `/items` nor the `tags=["items"]` to each *path ope
But we can still add _more_ `tags` that will be applied to a specific *path operation*, and also some extra `responses` specific to that *path operation*:
{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[30:31] title["app/routers/items.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[30:31] title["app/routers/items.py"] *}
/// tip
@@ -305,13 +305,13 @@ You import and create a `FastAPI` class as normally.
And we can even declare [global dependencies](dependencies/global-dependencies.md){.internal-link target=_blank} that will be combined with the dependencies for each `APIRouter`:
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[1,3,7] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[1,3,7] title["app/main.py"] *}
### Import the `APIRouter` { #import-the-apirouter }
Now we import the other submodules that have `APIRouter`s:
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[4:5] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[4:5] title["app/main.py"] *}
As the files `app/routers/users.py` and `app/routers/items.py` are submodules that are part of the same Python package `app`, we can use a single dot `.` to import them using "relative imports".
@@ -374,13 +374,13 @@ the `router` from `users` would overwrite the one from `items` and we wouldn't b
So, to be able to use both of them in the same file, we import the submodules directly:
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[5] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[5] title["app/main.py"] *}
### Include the `APIRouter`s for `users` and `items` { #include-the-apirouters-for-users-and-items }
Now, let's include the `router`s from the submodules `users` and `items`:
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[10:11] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[10:11] title["app/main.py"] *}
/// info
@@ -420,13 +420,13 @@ It contains an `APIRouter` with some admin *path operations* that your organizat
For this example it will be super simple. But let's say that because it is shared with other projects in the organization, we cannot modify it and add a `prefix`, `dependencies`, `tags`, etc. directly to the `APIRouter`:
{* ../../docs_src/bigger_applications/app_an_py39/internal/admin.py hl[3] title["app/internal/admin.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/internal/admin.py hl[3] title["app/internal/admin.py"] *}
But we still want to set a custom `prefix` when including the `APIRouter` so that all its *path operations* start with `/admin`, we want to secure it with the `dependencies` we already have for this project, and we want to include `tags` and `responses`.
We can declare all that without having to modify the original `APIRouter` by passing those parameters to `app.include_router()`:
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[14:17] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[14:17] title["app/main.py"] *}
That way, the original `APIRouter` will stay unmodified, so we can still share that same `app/internal/admin.py` file with other projects in the organization.
@@ -447,7 +447,7 @@ We can also add *path operations* directly to the `FastAPI` app.
Here we do it... just to show that we can 🤷:
{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[21:23] title["app/main.py"] *}
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[21:23] title["app/main.py"] *}
and it will work correctly, together with all the other *path operations* added with `app.include_router()`.

View File

@@ -102,12 +102,6 @@ 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
```
Or in Python 3.10 and above:
```Python
q: str | None = None
```

View File

@@ -164,7 +164,7 @@ images: list[Image]
as in:
{* ../../docs_src/body_nested_models/tutorial008_py39.py hl[13] *}
{* ../../docs_src/body_nested_models/tutorial008_py310.py hl[13] *}
## Editor support everywhere { #editor-support-everywhere }
@@ -194,7 +194,7 @@ That's what we are going to see here.
In this case, you would accept any `dict` as long as it has `int` keys with `float` values:
{* ../../docs_src/body_nested_models/tutorial009_py39.py hl[7] *}
{* ../../docs_src/body_nested_models/tutorial009_py310.py hl[7] *}
/// tip

View File

@@ -155,7 +155,7 @@ The function parameters will be recognized as follows:
FastAPI will know that the value of `q` is not required because of the default value `= None`.
The `str | None` (Python 3.10+) or `Union` in `Union[str, None]` (Python 3.9+) is not used by FastAPI to determine that the value is not required, it will know it's not required because it has a default value of `= None`.
The `str | None` is not used by FastAPI to determine that the value is not required, it will know it's not required because it has a default value of `= None`.
But adding the type annotations will allow your editor to give you better support and detect errors.

View File

@@ -46,7 +46,7 @@ But even if you **fill the data** and click "Execute", because the docs UI works
In some special use cases (probably not very common), you might want to **restrict** the cookies that you want to receive.
Your API now has the power to control its own <abbr title="This is a joke, just in case. It has nothing to do with cookie consents, but it's funny that even the API can now reject the poor cookies. Have a cookie. 🍪">cookie consent</abbr>. 🤪🍪
Your API now has the power to control its own <dfn title="This is a joke, just in case. It has nothing to do with cookie consents, but it's funny that even the API can now reject the poor cookies. Have a cookie. 🍪">cookie consent</dfn>. 🤪🍪
You can use Pydantic's model configuration to `forbid` any `extra` fields:
@@ -54,9 +54,9 @@ You can use Pydantic's model configuration to `forbid` any `extra` fields:
If a client tries to send some **extra cookies**, they will receive an **error** response.
Poor cookie banners with all their effort to get your consent for the <abbr title="This is another joke. Don't pay attention to me. Have some coffee for your cookie. ☕">API to reject it</abbr>. 🍪
Poor cookie banners with all their effort to get your consent for the <dfn title="This is another joke. Don't pay attention to me. Have some coffee for your cookie. ☕">API to reject it</dfn>. 🍪
For example, if the client tries to send a `santa_tracker` cookie with a value of `good-list-please`, the client will receive an **error** response telling them that the `santa_tracker` <abbr title="Santa disapproves the lack of cookies. 🎅 Okay, no more cookie jokes.">cookie is not allowed</abbr>:
For example, if the client tries to send a `santa_tracker` cookie with a value of `good-list-please`, the client will receive an **error** response telling them that the `santa_tracker` <dfn title="Santa disapproves the lack of cookies. 🎅 Okay, no more cookie jokes.">cookie is not allowed</dfn>:
```json
{
@@ -73,4 +73,4 @@ For example, if the client tries to send a `santa_tracker` cookie with a value o
## Summary { #summary }
You can use **Pydantic models** to declare <abbr title="Have a last cookie before you go. 🍪">**cookies**</abbr> in **FastAPI**. 😎
You can use **Pydantic models** to declare <dfn title="Have a last cookie before you go. 🍪">**cookies**</dfn> in **FastAPI**. 😎

View File

@@ -46,7 +46,7 @@ You can also specify whether your backend allows:
* Specific HTTP methods (`POST`, `PUT`) or all of them with the wildcard `"*"`.
* Specific HTTP headers or all of them with the wildcard `"*"`.
{* ../../docs_src/cors/tutorial001_py39.py hl[2,6:11,13:19] *}
{* ../../docs_src/cors/tutorial001_py310.py hl[2,6:11,13:19] *}
The default parameters used by the `CORSMiddleware` implementation are restrictive by default, so you'll need to explicitly enable particular origins, methods, or headers, in order for browsers to be permitted to use them in a Cross-Domain context.

View File

@@ -6,7 +6,7 @@ You can connect the debugger in your editor, for example with Visual Studio Code
In your FastAPI application, import and run `uvicorn` directly:
{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *}
{* ../../docs_src/debugging/tutorial001_py310.py hl[1,15] *}
### About `__name__ == "__main__"` { #about-name-main }

View File

@@ -101,7 +101,7 @@ Now you can declare your dependency using this class.
Notice how we write `CommonQueryParams` twice in the above code:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -109,7 +109,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
////
//// tab | Python 3.9+ non-Annotated
//// tab | Python 3.10+ non-Annotated
/// tip
@@ -137,7 +137,7 @@ It is from this one that FastAPI will extract the declared parameters and that i
In this case, the first `CommonQueryParams`, in:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python
commons: Annotated[CommonQueryParams, ...
@@ -145,7 +145,7 @@ commons: Annotated[CommonQueryParams, ...
////
//// tab | Python 3.9+ non-Annotated
//// tab | Python 3.10+ non-Annotated
/// tip
@@ -163,7 +163,7 @@ commons: CommonQueryParams ...
You could actually write just:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python
commons: Annotated[Any, Depends(CommonQueryParams)]
@@ -171,7 +171,7 @@ commons: Annotated[Any, Depends(CommonQueryParams)]
////
//// tab | Python 3.9+ non-Annotated
//// tab | Python 3.10+ non-Annotated
/// tip
@@ -197,7 +197,7 @@ But declaring the type is encouraged as that way your editor will know what will
But you see that we are having some code repetition here, writing `CommonQueryParams` twice:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -205,7 +205,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
////
//// tab | Python 3.9+ non-Annotated
//// tab | Python 3.10+ non-Annotated
/// tip
@@ -225,7 +225,7 @@ For those specific cases, you can do the following:
Instead of writing:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -233,7 +233,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
////
//// tab | Python 3.9+ non-Annotated
//// tab | Python 3.10+ non-Annotated
/// tip
@@ -249,7 +249,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
...you write:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python
commons: Annotated[CommonQueryParams, Depends()]
@@ -257,7 +257,7 @@ commons: Annotated[CommonQueryParams, Depends()]
////
//// tab | Python 3.9+ non-Annotated
//// tab | Python 3.10+ non-Annotated
/// tip

View File

@@ -14,7 +14,7 @@ The *path operation decorator* receives an optional argument `dependencies`.
It should be a `list` of `Depends()`:
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[19] *}
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[19] *}
These dependencies will be executed/solved the same way as normal dependencies. But their value (if they return any) won't be passed to your *path operation function*.
@@ -44,13 +44,13 @@ You can use the same dependency *functions* you use normally.
They can declare request requirements (like headers) or other sub-dependencies:
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[8,13] *}
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[8,13] *}
### Raise exceptions { #raise-exceptions }
These dependencies can `raise` exceptions, the same as normal dependencies:
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[10,15] *}
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[10,15] *}
### Return values { #return-values }
@@ -58,7 +58,7 @@ And they can return values or not, the values won't be used.
So, you can reuse a normal dependency (that returns a value) you already use somewhere else, and even though the value won't be used, the dependency will be executed:
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[11,16] *}
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[11,16] *}
## Dependencies for a group of *path operations* { #dependencies-for-a-group-of-path-operations }

View File

@@ -1,6 +1,6 @@
# Dependencies with yield { #dependencies-with-yield }
FastAPI supports dependencies that do some <abbr title='sometimes also called "exit code", "cleanup code", "teardown code", "closing code", "context manager exit code", etc.'>extra steps after finishing</abbr>.
FastAPI supports dependencies that do some <dfn title='sometimes also called "exit code", "cleanup code", "teardown code", "closing code", "context manager exit code", etc.'>extra steps after finishing</dfn>.
To do this, use `yield` instead of `return`, and write the extra steps (code) after.
@@ -29,15 +29,15 @@ For example, you could use this to create a database session and close it after
Only the code prior to and including the `yield` statement is executed before creating a response:
{* ../../docs_src/dependencies/tutorial007_py39.py hl[2:4] *}
{* ../../docs_src/dependencies/tutorial007_py310.py hl[2:4] *}
The yielded value is what is injected into *path operations* and other dependencies:
{* ../../docs_src/dependencies/tutorial007_py39.py hl[4] *}
{* ../../docs_src/dependencies/tutorial007_py310.py hl[4] *}
The code following the `yield` statement is executed after the response:
{* ../../docs_src/dependencies/tutorial007_py39.py hl[5:6] *}
{* ../../docs_src/dependencies/tutorial007_py310.py hl[5:6] *}
/// tip
@@ -57,7 +57,7 @@ So, you can look for that specific exception inside the dependency with `except
In the same way, you can use `finally` to make sure the exit steps are executed, no matter if there was an exception or not.
{* ../../docs_src/dependencies/tutorial007_py39.py hl[3,5] *}
{* ../../docs_src/dependencies/tutorial007_py310.py hl[3,5] *}
## Sub-dependencies with `yield` { #sub-dependencies-with-yield }
@@ -67,7 +67,7 @@ You can have sub-dependencies and "trees" of sub-dependencies of any size and sh
For example, `dependency_c` can have a dependency on `dependency_b`, and `dependency_b` on `dependency_a`:
{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[6,14,22] *}
{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[6,14,22] *}
And all of them can use `yield`.
@@ -75,7 +75,7 @@ In this case `dependency_c`, to execute its exit code, needs the value from `dep
And, in turn, `dependency_b` needs the value from `dependency_a` (here named `dep_a`) to be available for its exit code.
{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[18:19,26:27] *}
{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[18:19,26:27] *}
The same way, you could have some dependencies with `yield` and some other dependencies with `return`, and have some of those depend on some of the others.
@@ -109,7 +109,7 @@ But it's there for you if you need it. 🤓
///
{* ../../docs_src/dependencies/tutorial008b_an_py39.py hl[18:22,31] *}
{* ../../docs_src/dependencies/tutorial008b_an_py310.py hl[18:22,31] *}
If you want to catch exceptions and create a custom response based on that, create a [Custom Exception Handler](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
@@ -117,7 +117,7 @@ If you want to catch exceptions and create a custom response based on that, crea
If you catch an exception using `except` in a dependency with `yield` and you don't raise it again (or raise a new exception), FastAPI won't be able to notice there was an exception, the same way that would happen with regular Python:
{* ../../docs_src/dependencies/tutorial008c_an_py39.py hl[15:16] *}
{* ../../docs_src/dependencies/tutorial008c_an_py310.py hl[15:16] *}
In this case, the client will see an *HTTP 500 Internal Server Error* response as it should, given that we are not raising an `HTTPException` or similar, but the server will **not have any logs** or any other indication of what was the error. 😱
@@ -127,7 +127,7 @@ If you catch an exception in a dependency with `yield`, unless you are raising a
You can re-raise the same exception using `raise`:
{* ../../docs_src/dependencies/tutorial008d_an_py39.py hl[17] *}
{* ../../docs_src/dependencies/tutorial008d_an_py310.py hl[17] *}
Now the client will get the same *HTTP 500 Internal Server Error* response, but the server will have our custom `InternalError` in the logs. 😎
@@ -190,7 +190,7 @@ Normally the exit code of dependencies with `yield` is executed **after the resp
But if you know that you won't need to use the dependency after returning from the *path operation function*, you can use `Depends(scope="function")` to tell FastAPI that it should close the dependency after the *path operation function* returns, but **before** the **response is sent**.
{* ../../docs_src/dependencies/tutorial008e_an_py39.py hl[12,16] *}
{* ../../docs_src/dependencies/tutorial008e_an_py310.py hl[12,16] *}
`Depends()` receives a `scope` parameter that can be:
@@ -269,7 +269,7 @@ In Python, you can create Context Managers by <a href="https://docs.python.org/3
You can also use them inside of **FastAPI** dependencies with `yield` by using
`with` or `async with` statements inside of the dependency function:
{* ../../docs_src/dependencies/tutorial010_py39.py hl[1:9,13] *}
{* ../../docs_src/dependencies/tutorial010_py310.py hl[1:9,13] *}
/// tip

View File

@@ -6,7 +6,7 @@ Similar to the way you can [add `dependencies` to the *path operation decorators
In that case, they will be applied to all the *path operations* in the application:
{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[17] *}
{* ../../docs_src/dependencies/tutorial012_an_py310.py hl[17] *}
And all the ideas in the section about [adding `dependencies` to the *path operation decorators*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} still apply, but in this case, to all of the *path operations* in the app.

View File

@@ -1,6 +1,6 @@
# Dependencies { #dependencies }
**FastAPI** has a very powerful but intuitive **<abbr title="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** system.
**FastAPI** has a very powerful but intuitive **<dfn title="also known as components, resources, providers, services, injectables">Dependency Injection</dfn>** system.
It is designed to be very simple to use, and to make it very easy for any developer to integrate other components with **FastAPI**.

View File

@@ -58,11 +58,11 @@ query_extractor --> query_or_cookie_extractor --> read_query
If one of your dependencies is declared multiple times for the same *path operation*, for example, multiple dependencies have a common sub-dependency, **FastAPI** will know to call that sub-dependency only once per request.
And it will save the returned value in a <abbr title="A utility/system to store computed/generated values, to reuse them instead of computing them again.">"cache"</abbr> and pass it to all the "dependants" that need it in that specific request, instead of calling the dependency multiple times for the same request.
And it will save the returned value in a <dfn title="A utility/system to store computed/generated values, to reuse them instead of computing them again.">"cache"</dfn> and pass it to all the "dependants" that need it in that specific request, instead of calling the dependency multiple times for the same request.
In an advanced scenario where you know you need the dependency to be called at every step (possibly multiple times) in the same request instead of using the "cached" value, you can set the parameter `use_cache=False` when using `Depends`:
//// tab | Python 3.9+
//// tab | Python 3.10+
```Python hl_lines="1"
async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
@@ -71,7 +71,7 @@ async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_ca
////
//// tab | Python 3.9+ non-Annotated
//// tab | Python 3.10+ non-Annotated
/// tip

View File

@@ -190,9 +190,9 @@ But if we put that in the assignment `response_model=PlaneItem | CarItem` we wou
The same way, you can declare responses of lists of objects.
For that, use the standard Python `typing.List` (or just `list` in Python 3.9 and above):
For that, use the standard Python `list`:
{* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *}
{* ../../docs_src/extra_models/tutorial004_py310.py hl[18] *}
## Response with arbitrary `dict` { #response-with-arbitrary-dict }
@@ -200,9 +200,9 @@ You can also declare a response using a plain arbitrary `dict`, declaring just t
This is useful if you don't know the valid field/attribute names (that would be needed for a Pydantic model) beforehand.
In this case, you can use `typing.Dict` (or just `dict` in Python 3.9 and above):
In this case, you can use `dict`:
{* ../../docs_src/extra_models/tutorial005_py39.py hl[6] *}
{* ../../docs_src/extra_models/tutorial005_py310.py hl[6] *}
## Recap { #recap }

View File

@@ -2,7 +2,7 @@
The simplest FastAPI file could look like this:
{* ../../docs_src/first_steps/tutorial001_py39.py *}
{* ../../docs_src/first_steps/tutorial001_py310.py *}
Copy that to a file `main.py`.
@@ -54,7 +54,7 @@ In the output, there's a line with something like:
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
That line shows the URL where your app is being served, in your local machine.
That line shows the URL where your app is being served on your local machine.
### Check it { #check-it }
@@ -183,7 +183,7 @@ That's it! Now you can access your app at that URL. ✨
### Step 1: import `FastAPI` { #step-1-import-fastapi }
{* ../../docs_src/first_steps/tutorial001_py39.py hl[1] *}
{* ../../docs_src/first_steps/tutorial001_py310.py hl[1] *}
`FastAPI` is a Python class that provides all the functionality for your API.
@@ -197,7 +197,7 @@ You can use all the <a href="https://www.starlette.dev/" class="external-link" t
### Step 2: create a `FastAPI` "instance" { #step-2-create-a-fastapi-instance }
{* ../../docs_src/first_steps/tutorial001_py39.py hl[3] *}
{* ../../docs_src/first_steps/tutorial001_py310.py hl[3] *}
Here the `app` variable will be an "instance" of the class `FastAPI`.
@@ -266,12 +266,12 @@ We are going to call them "**operations**" too.
#### Define a *path operation decorator* { #define-a-path-operation-decorator }
{* ../../docs_src/first_steps/tutorial001_py39.py hl[6] *}
{* ../../docs_src/first_steps/tutorial001_py310.py hl[6] *}
The `@app.get("/")` tells **FastAPI** that the function right below is in charge of handling requests that go to:
* the path `/`
* using a <abbr title="an HTTP GET method"><code>get</code> operation</abbr>
* using a <dfn title="an HTTP GET method"><code>get</code> operation</dfn>
/// info | `@decorator` Info
@@ -320,7 +320,7 @@ This is our "**path operation function**":
* **operation**: is `get`.
* **function**: is the function below the "decorator" (below `@app.get("/")`).
{* ../../docs_src/first_steps/tutorial001_py39.py hl[7] *}
{* ../../docs_src/first_steps/tutorial001_py310.py hl[7] *}
This is a Python function.
@@ -332,7 +332,7 @@ In this case, it is an `async` function.
You could also define it as a normal function instead of `async def`:
{* ../../docs_src/first_steps/tutorial003_py39.py hl[7] *}
{* ../../docs_src/first_steps/tutorial003_py310.py hl[7] *}
/// note
@@ -342,7 +342,7 @@ If you don't know the difference, check the [Async: *"In a hurry?"*](../async.md
### Step 5: return the content { #step-5-return-the-content }
{* ../../docs_src/first_steps/tutorial001_py39.py hl[8] *}
{* ../../docs_src/first_steps/tutorial001_py310.py hl[8] *}
You can return a `dict`, `list`, singular values as `str`, `int`, etc.

View File

@@ -25,7 +25,7 @@ To return HTTP responses with errors to the client you use `HTTPException`.
### Import `HTTPException` { #import-httpexception }
{* ../../docs_src/handling_errors/tutorial001_py39.py hl[1] *}
{* ../../docs_src/handling_errors/tutorial001_py310.py hl[1] *}
### Raise an `HTTPException` in your code { #raise-an-httpexception-in-your-code }
@@ -39,7 +39,7 @@ The benefit of raising an exception over returning a value will be more evident
In this example, when the client requests an item by an ID that doesn't exist, raise an exception with a status code of `404`:
{* ../../docs_src/handling_errors/tutorial001_py39.py hl[11] *}
{* ../../docs_src/handling_errors/tutorial001_py310.py hl[11] *}
### The resulting response { #the-resulting-response }
@@ -77,7 +77,7 @@ You probably won't need to use it directly in your code.
But in case you needed it for an advanced scenario, you can add custom headers:
{* ../../docs_src/handling_errors/tutorial002_py39.py hl[14] *}
{* ../../docs_src/handling_errors/tutorial002_py310.py hl[14] *}
## Install custom exception handlers { #install-custom-exception-handlers }
@@ -89,7 +89,7 @@ And you want to handle this exception globally with FastAPI.
You could add a custom exception handler with `@app.exception_handler()`:
{* ../../docs_src/handling_errors/tutorial003_py39.py hl[5:7,13:18,24] *}
{* ../../docs_src/handling_errors/tutorial003_py310.py hl[5:7,13:18,24] *}
Here, if you request `/unicorns/yolo`, the *path operation* will `raise` a `UnicornException`.
@@ -127,7 +127,7 @@ To override it, import the `RequestValidationError` and use it with `@app.except
The exception handler will receive a `Request` and the exception.
{* ../../docs_src/handling_errors/tutorial004_py39.py hl[2,14:19] *}
{* ../../docs_src/handling_errors/tutorial004_py310.py hl[2,14:19] *}
Now, if you go to `/items/foo`, instead of getting the default JSON error with:
@@ -159,7 +159,7 @@ The same way, you can override the `HTTPException` handler.
For example, you could want to return a plain text response instead of JSON for these errors:
{* ../../docs_src/handling_errors/tutorial004_py39.py hl[3:4,9:11,25] *}
{* ../../docs_src/handling_errors/tutorial004_py310.py hl[3:4,9:11,25] *}
/// note | Technical Details
@@ -183,7 +183,7 @@ The `RequestValidationError` contains the `body` it received with invalid data.
You could use it while developing your app to log the body and debug it, return it to the user, etc.
{* ../../docs_src/handling_errors/tutorial005_py39.py hl[14] *}
{* ../../docs_src/handling_errors/tutorial005_py310.py hl[14] *}
Now try sending an invalid item like:
@@ -239,6 +239,6 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
If you want to use the exception along with the same default exception handlers from **FastAPI**, you can import and reuse the default exception handlers from `fastapi.exception_handlers`:
{* ../../docs_src/handling_errors/tutorial006_py39.py hl[2:5,15,21] *}
{* ../../docs_src/handling_errors/tutorial006_py310.py hl[2:5,15,21] *}
In this example you are just printing the error with a very expressive message, but you get the idea. You can use the exception and then just reuse the default exception handlers.

View File

@@ -18,7 +18,7 @@ You can set the following fields that are used in the OpenAPI specification and
You can set them as follows:
{* ../../docs_src/metadata/tutorial001_py39.py hl[3:16, 19:32] *}
{* ../../docs_src/metadata/tutorial001_py310.py hl[3:16, 19:32] *}
/// tip
@@ -36,7 +36,7 @@ Since OpenAPI 3.1.0 and FastAPI 0.99.0, you can also set the `license_info` with
For example:
{* ../../docs_src/metadata/tutorial001_1_py39.py hl[31] *}
{* ../../docs_src/metadata/tutorial001_1_py310.py hl[31] *}
## Metadata for tags { #metadata-for-tags }
@@ -58,7 +58,7 @@ Let's try that in an example with tags for `users` and `items`.
Create metadata for your tags and pass it to the `openapi_tags` parameter:
{* ../../docs_src/metadata/tutorial004_py39.py hl[3:16,18] *}
{* ../../docs_src/metadata/tutorial004_py310.py hl[3:16,18] *}
Notice that you can use Markdown inside of the descriptions, for example "login" will be shown in bold (**login**) and "fancy" will be shown in italics (_fancy_).
@@ -72,7 +72,7 @@ You don't have to add metadata for all the tags that you use.
Use the `tags` parameter with your *path operations* (and `APIRouter`s) to assign them to different tags:
{* ../../docs_src/metadata/tutorial004_py39.py hl[21,26] *}
{* ../../docs_src/metadata/tutorial004_py310.py hl[21,26] *}
/// info
@@ -100,7 +100,7 @@ But you can configure it with the parameter `openapi_url`.
For example, to set it to be served at `/api/v1/openapi.json`:
{* ../../docs_src/metadata/tutorial002_py39.py hl[3] *}
{* ../../docs_src/metadata/tutorial002_py310.py hl[3] *}
If you want to disable the OpenAPI schema completely you can set `openapi_url=None`, that will also disable the documentation user interfaces that use it.
@@ -117,4 +117,4 @@ You can configure the two documentation user interfaces included:
For example, to set Swagger UI to be served at `/documentation` and disable ReDoc:
{* ../../docs_src/metadata/tutorial003_py39.py hl[3] *}
{* ../../docs_src/metadata/tutorial003_py310.py hl[3] *}

View File

@@ -31,7 +31,7 @@ The middleware function receives:
* Then it returns the `response` generated by the corresponding *path operation*.
* You can then further modify the `response` before returning it.
{* ../../docs_src/middleware/tutorial001_py39.py hl[8:9,11,14] *}
{* ../../docs_src/middleware/tutorial001_py310.py hl[8:9,11,14] *}
/// tip
@@ -57,7 +57,7 @@ And also after the `response` is generated, before returning it.
For example, you could add a custom header `X-Process-Time` containing the time in seconds that it took to process the request and generate a response:
{* ../../docs_src/middleware/tutorial001_py39.py hl[10,12:13] *}
{* ../../docs_src/middleware/tutorial001_py310.py hl[10,12:13] *}
/// tip

View File

@@ -46,17 +46,17 @@ In these cases, it could make sense to store the tags in an `Enum`.
**FastAPI** supports that the same way as with plain strings:
{* ../../docs_src/path_operation_configuration/tutorial002b_py39.py hl[1,8:10,13,18] *}
{* ../../docs_src/path_operation_configuration/tutorial002b_py310.py hl[1,8:10,13,18] *}
## Summary and description { #summary-and-description }
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 }
As descriptions tend to be long and cover multiple lines, you can declare the *path operation* description in the function <abbr title="a multi-line string as the first expression inside a function (not assigned to any variable) used for documentation">docstring</abbr> and **FastAPI** will read it from there.
As descriptions tend to be long and cover multiple lines, you can declare the *path operation* description in the function <dfn title="a multi-line string as the first expression inside a function (not assigned to any variable) used for documentation">docstring</dfn> and **FastAPI** will read it from there.
You can write <a href="https://en.wikipedia.org/wiki/Markdown" class="external-link" target="_blank">Markdown</a> in the docstring, it will be interpreted and displayed correctly (taking into account docstring indentation).
@@ -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
@@ -90,9 +90,9 @@ So, if you don't provide one, **FastAPI** will automatically generate one of "Su
## Deprecate a *path operation* { #deprecate-a-path-operation }
If you need to mark a *path operation* as <abbr title="obsolete, recommended not to use it">deprecated</abbr>, but without removing it, pass the parameter `deprecated`:
If you need to mark a *path operation* as <dfn title="obsolete, recommended not to use it">deprecated</dfn>, but without removing it, pass the parameter `deprecated`:
{* ../../docs_src/path_operation_configuration/tutorial006_py39.py hl[16] *}
{* ../../docs_src/path_operation_configuration/tutorial006_py310.py hl[16] *}
It will be clearly marked as deprecated in the interactive docs:

View File

@@ -54,11 +54,11 @@ It doesn't matter for **FastAPI**. It will detect the parameters by their names,
So, you can declare your function as:
{* ../../docs_src/path_params_numeric_validations/tutorial002_py39.py hl[7] *}
{* ../../docs_src/path_params_numeric_validations/tutorial002_py310.py hl[7] *}
But keep in mind that if you use `Annotated`, you won't have this problem, it won't matter as you're not using the function parameter default values for `Query()` or `Path()`.
{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py *}
{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py310.py *}
## Order the parameters as you need, tricks { #order-the-parameters-as-you-need-tricks }
@@ -83,13 +83,13 @@ Pass `*`, as the first parameter of the function.
Python won't do anything with that `*`, but it will know that all the following parameters should be called as keyword arguments (key-value pairs), also known as <abbr title="From: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>. Even if they don't have a default value.
{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *}
{* ../../docs_src/path_params_numeric_validations/tutorial003_py310.py hl[7] *}
### Better with `Annotated` { #better-with-annotated }
Keep in mind that if you use `Annotated`, as you are not using function parameter default values, you won't have this problem, and you probably won't need to use `*`.
{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py hl[10] *}
{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py310.py hl[10] *}
## Number validations: greater than or equal { #number-validations-greater-than-or-equal }
@@ -97,7 +97,7 @@ With `Query` and `Path` (and others you'll see later) you can declare number con
Here, with `ge=1`, `item_id` will need to be an integer number "`g`reater than or `e`qual" to `1`.
{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py hl[10] *}
{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py310.py hl[10] *}
## Number validations: greater than and less than or equal { #number-validations-greater-than-and-less-than-or-equal }
@@ -106,7 +106,7 @@ The same applies for:
* `gt`: `g`reater `t`han
* `le`: `l`ess than or `e`qual
{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py hl[10] *}
{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py310.py hl[10] *}
## Number validations: floats, greater than and less than { #number-validations-floats-greater-than-and-less-than }
@@ -118,7 +118,7 @@ So, `0.5` would be a valid value. But `0.0` or `0` would not.
And the same for <abbr title="less than"><code>lt</code></abbr>.
{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py hl[13] *}
{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py310.py hl[13] *}
## Recap { #recap }

View File

@@ -2,7 +2,7 @@
You can declare path "parameters" or "variables" with the same syntax used by Python format strings:
{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *}
{* ../../docs_src/path_params/tutorial001_py310.py hl[6:7] *}
The value of the path parameter `item_id` will be passed to your function as the argument `item_id`.
@@ -16,7 +16,7 @@ So, if you run this example and go to <a href="http://127.0.0.1:8000/items/foo"
You can declare the type of a path parameter in the function, using standard Python type annotations:
{* ../../docs_src/path_params/tutorial002_py39.py hl[7] *}
{* ../../docs_src/path_params/tutorial002_py310.py hl[7] *}
In this case, `item_id` is declared to be an `int`.
@@ -26,7 +26,7 @@ This will give you editor support inside of your function, with error checks, co
///
## Data <abbr title="also known as: serialization, parsing, marshalling">conversion</abbr> { #data-conversion }
## Data <dfn title="also known as: serialization, parsing, marshalling">conversion</dfn> { #data-conversion }
If you run this example and open your browser at <a href="http://127.0.0.1:8000/items/3" class="external-link" target="_blank">http://127.0.0.1:8000/items/3</a>, you will see a response of:
@@ -38,7 +38,7 @@ If you run this example and open your browser at <a href="http://127.0.0.1:8000/
Notice that the value your function received (and returned) is `3`, as a Python `int`, not a string `"3"`.
So, with that type declaration, **FastAPI** gives you automatic request <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>.
So, with that type declaration, **FastAPI** gives you automatic request <dfn title="converting the string that comes from an HTTP request into Python data">"parsing"</dfn>.
///
@@ -118,13 +118,13 @@ And then you can also have a path `/users/{user_id}` to get data about a specifi
Because *path operations* are evaluated in order, you need to make sure that the path for `/users/me` is declared before the one for `/users/{user_id}`:
{* ../../docs_src/path_params/tutorial003_py39.py hl[6,11] *}
{* ../../docs_src/path_params/tutorial003_py310.py hl[6,11] *}
Otherwise, the path for `/users/{user_id}` would match also for `/users/me`, "thinking" that it's receiving a parameter `user_id` with a value of `"me"`.
Similarly, you cannot redefine a path operation:
{* ../../docs_src/path_params/tutorial003b_py39.py hl[6,11] *}
{* ../../docs_src/path_params/tutorial003b_py310.py hl[6,11] *}
The first one will always be used since the path matches first.
@@ -140,11 +140,11 @@ By inheriting from `str` the API docs will be able to know that the values must
Then create class attributes with fixed values, which will be the available valid values:
{* ../../docs_src/path_params/tutorial005_py39.py hl[1,6:9] *}
{* ../../docs_src/path_params/tutorial005_py310.py hl[1,6:9] *}
/// tip
If you are wondering, "AlexNet", "ResNet", and "LeNet" are just names of Machine Learning <abbr title="Technically, Deep Learning model architectures">models</abbr>.
If you are wondering, "AlexNet", "ResNet", and "LeNet" are just names of Machine Learning <dfn title="Technically, Deep Learning model architectures">models</dfn>.
///
@@ -152,7 +152,7 @@ If you are wondering, "AlexNet", "ResNet", and "LeNet" are just names of Machine
Then create a *path parameter* with a type annotation using the enum class you created (`ModelName`):
{* ../../docs_src/path_params/tutorial005_py39.py hl[16] *}
{* ../../docs_src/path_params/tutorial005_py310.py hl[16] *}
### Check the docs { #check-the-docs }
@@ -168,13 +168,13 @@ The value of the *path parameter* will be an *enumeration member*.
You can compare it with the *enumeration member* in your created enum `ModelName`:
{* ../../docs_src/path_params/tutorial005_py39.py hl[17] *}
{* ../../docs_src/path_params/tutorial005_py310.py hl[17] *}
#### Get the *enumeration value* { #get-the-enumeration-value }
You can get the actual value (a `str` in this case) using `model_name.value`, or in general, `your_enum_member.value`:
{* ../../docs_src/path_params/tutorial005_py39.py hl[20] *}
{* ../../docs_src/path_params/tutorial005_py310.py hl[20] *}
/// tip
@@ -188,7 +188,7 @@ You can return *enum members* from your *path operation*, even nested in a JSON
They will be converted to their corresponding values (strings in this case) before returning them to the client:
{* ../../docs_src/path_params/tutorial005_py39.py hl[18,21,23] *}
{* ../../docs_src/path_params/tutorial005_py310.py hl[18,21,23] *}
In your client you will get a JSON response like:
@@ -227,7 +227,7 @@ In this case, the name of the parameter is `file_path`, and the last part, `:pat
So, you can use it with:
{* ../../docs_src/path_params/tutorial004_py39.py hl[6] *}
{* ../../docs_src/path_params/tutorial004_py310.py hl[6] *}
/// tip
@@ -242,7 +242,7 @@ In that case, the URL would be: `/files//home/johndoe/myfile.txt`, with a double
With **FastAPI**, by using short, intuitive and standard Python type declarations, you get:
* Editor support: error checks, autocompletion, etc.
* Data "<abbr title="converting the string that comes from an HTTP request into Python data">parsing</abbr>"
* Data "<dfn title="converting the string that comes from an HTTP request into Python data">parsing</dfn>"
* Data validation
* API annotation and automatic documentation

View File

@@ -47,40 +47,16 @@ Now it's the time to use it with FastAPI. 🚀
We had this type annotation:
//// tab | Python 3.10+
```Python
q: str | None = None
```
////
//// tab | Python 3.9+
```Python
q: Union[str, None] = None
```
////
What we will do is wrap that with `Annotated`, so it becomes:
//// tab | Python 3.10+
```Python
q: Annotated[str | None] = None
```
////
//// tab | Python 3.9+
```Python
q: Annotated[Union[str, None]] = None
```
////
Both of those versions mean the same thing, `q` is a parameter that can be a `str` or `None`, and by default, it is `None`.
Now let's jump to the fun stuff. 🎉
@@ -109,7 +85,7 @@ FastAPI will now:
## Alternative (old): `Query` as the default value { #alternative-old-query-as-the-default-value }
Previous versions of FastAPI (before <abbr title="before 2023-03">0.95.0</abbr>) required you to use `Query` as the default value of your parameter, instead of putting it in `Annotated`, there's a high chance that you will see code using it around, so I'll explain it to you.
Previous versions of FastAPI (before <dfn title="before 2023-03">0.95.0</dfn>) required you to use `Query` as the default value of your parameter, instead of putting it in `Annotated`, there's a high chance that you will see code using it around, so I'll explain it to you.
/// tip
@@ -192,7 +168,7 @@ You can also add a parameter `min_length`:
## Add regular expressions { #add-regular-expressions }
You can define a <abbr title="A regular expression, regex or regexp is a sequence of characters that define a search pattern for strings.">regular expression</abbr> `pattern` that the parameter should match:
You can define a <dfn title="A regular expression, regex or regexp is a sequence of characters that define a search pattern for strings.">regular expression</dfn> `pattern` that the parameter should match:
{* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *}
@@ -212,7 +188,7 @@ You can, of course, use default values other than `None`.
Let's say that you want to declare the `q` query parameter to have a `min_length` of `3`, and to have a default value of `"fixedquery"`:
{* ../../docs_src/query_params_str_validations/tutorial005_an_py39.py hl[9] *}
{* ../../docs_src/query_params_str_validations/tutorial005_an_py310.py hl[9] *}
/// note
@@ -242,7 +218,7 @@ q: Annotated[str | None, Query(min_length=3)] = None
So, when you need to declare a value as required while using `Query`, you can simply not declare a default value:
{* ../../docs_src/query_params_str_validations/tutorial006_an_py39.py hl[9] *}
{* ../../docs_src/query_params_str_validations/tutorial006_an_py310.py hl[9] *}
### Required, can be `None` { #required-can-be-none }
@@ -293,7 +269,7 @@ The interactive API docs will update accordingly, to allow multiple values:
You can also define a default `list` of values if none are provided:
{* ../../docs_src/query_params_str_validations/tutorial012_an_py39.py hl[9] *}
{* ../../docs_src/query_params_str_validations/tutorial012_an_py310.py hl[9] *}
If you go to:
@@ -316,7 +292,7 @@ the default of `q` will be: `["foo", "bar"]` and your response will be:
You can also use `list` directly instead of `list[str]`:
{* ../../docs_src/query_params_str_validations/tutorial013_an_py39.py hl[9] *}
{* ../../docs_src/query_params_str_validations/tutorial013_an_py310.py hl[9] *}
/// note
@@ -372,7 +348,7 @@ Then you can declare an `alias`, and that alias is what will be used to find the
Now let's say you don't like this parameter anymore.
You have to leave it there a while because there are clients using it, but you want the docs to clearly show it as <abbr title="obsolete, recommended not to use it">deprecated</abbr>.
You have to leave it there a while because there are clients using it, but you want the docs to clearly show it as <dfn title="obsolete, recommended not to use it">deprecated</dfn>.
Then pass the parameter `deprecated=True` to `Query`:
@@ -402,7 +378,7 @@ Pydantic also has <a href="https://docs.pydantic.dev/latest/concepts/validators/
///
For example, this custom validator checks that the item ID starts with `isbn-` for an <abbr title="ISBN means International Standard Book Number">ISBN</abbr> book number or with `imdb-` for an <abbr title="IMDB (Internet Movie Database) is a website with information about movies">IMDB</abbr> movie URL ID:
For example, this custom validator checks that the item ID starts with `isbn-` for an <abbr title="International Standard Book Number">ISBN</abbr> book number or with `imdb-` for an <abbr title="Internet Movie Database: a website with information about movies">IMDB</abbr> movie URL ID:
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
@@ -436,7 +412,7 @@ Did you notice? a string using `value.startswith()` can take a tuple, and it wil
#### A Random Item { #a-random-item }
With `data.items()` we get an <abbr title="Something we can iterate on with a for loop, like a list, set, etc.">iterable object</abbr> with tuples containing the key and value for each dictionary item.
With `data.items()` we get an <dfn title="Something we can iterate on with a for loop, like a list, set, etc.">iterable object</dfn> with tuples containing the key and value for each dictionary item.
We convert this iterable object into a proper `list` with `list(data.items())`.

View File

@@ -2,7 +2,7 @@
When you declare other function parameters that are not part of the path parameters, they are automatically interpreted as "query" parameters.
{* ../../docs_src/query_params/tutorial001_py39.py hl[9] *}
{* ../../docs_src/query_params/tutorial001_py310.py hl[9] *}
The query is the set of key-value pairs that go after the `?` in a URL, separated by `&` characters.
@@ -24,7 +24,7 @@ But when you declare them with Python types (in the example above, as `int`), th
All the same process that applied for path parameters also applies for query parameters:
* Editor support (obviously)
* Data <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>
* Data <dfn title="converting the string that comes from an HTTP request into Python data">"parsing"</dfn>
* Data validation
* Automatic documentation
@@ -128,7 +128,7 @@ If you don't want to add a specific value but just make it optional, set the def
But when you want to make a query parameter required, you can just not declare any default value:
{* ../../docs_src/query_params/tutorial005_py39.py hl[6:7] *}
{* ../../docs_src/query_params/tutorial005_py310.py hl[6:7] *}
Here the query parameter `needy` is a required query parameter of type `str`.

View File

@@ -20,13 +20,13 @@ This is because uploaded files are sent as "form data".
Import `File` and `UploadFile` from `fastapi`:
{* ../../docs_src/request_files/tutorial001_an_py39.py hl[3] *}
{* ../../docs_src/request_files/tutorial001_an_py310.py hl[3] *}
## Define `File` Parameters { #define-file-parameters }
Create file parameters the same way you would for `Body` or `Form`:
{* ../../docs_src/request_files/tutorial001_an_py39.py hl[9] *}
{* ../../docs_src/request_files/tutorial001_an_py310.py hl[9] *}
/// info
@@ -54,7 +54,7 @@ But there are several cases in which you might benefit from using `UploadFile`.
Define a file parameter with a type of `UploadFile`:
{* ../../docs_src/request_files/tutorial001_an_py39.py hl[14] *}
{* ../../docs_src/request_files/tutorial001_an_py310.py hl[14] *}
Using `UploadFile` has several advantages over `bytes`:
@@ -143,7 +143,7 @@ You can make a file optional by using standard type annotations and setting a de
You can also use `File()` with `UploadFile`, for example, to set additional metadata:
{* ../../docs_src/request_files/tutorial001_03_an_py39.py hl[9,15] *}
{* ../../docs_src/request_files/tutorial001_03_an_py310.py hl[9,15] *}
## Multiple File Uploads { #multiple-file-uploads }
@@ -153,7 +153,7 @@ They would be associated to the same "form field" sent using "form data".
To use that, declare a list of `bytes` or `UploadFile`:
{* ../../docs_src/request_files/tutorial002_an_py39.py hl[10,15] *}
{* ../../docs_src/request_files/tutorial002_an_py310.py hl[10,15] *}
You will receive, as declared, a `list` of `bytes` or `UploadFile`s.
@@ -169,7 +169,7 @@ You could also use `from starlette.responses import HTMLResponse`.
And the same way as before, you can use `File()` to set additional parameters, even for `UploadFile`:
{* ../../docs_src/request_files/tutorial003_an_py39.py hl[11,18:20] *}
{* ../../docs_src/request_files/tutorial003_an_py310.py hl[11,18:20] *}
## Recap { #recap }

View File

@@ -24,7 +24,7 @@ This is supported since FastAPI version `0.113.0`. 🤓
You just need to declare a **Pydantic model** with the fields you want to receive as **form fields**, and then declare the parameter as `Form`:
{* ../../docs_src/request_form_models/tutorial001_an_py39.py hl[9:11,15] *}
{* ../../docs_src/request_form_models/tutorial001_an_py310.py hl[9:11,15] *}
**FastAPI** will **extract** the data for **each field** from the **form data** in the request and give you the Pydantic model you defined.
@@ -48,7 +48,7 @@ This is supported since FastAPI version `0.114.0`. 🤓
You can use Pydantic's model configuration to `forbid` any `extra` fields:
{* ../../docs_src/request_form_models/tutorial002_an_py39.py hl[12] *}
{* ../../docs_src/request_form_models/tutorial002_an_py310.py hl[12] *}
If a client tries to send some extra data, they will receive an **error** response.

Some files were not shown because too many files have changed in this diff Show More