Compare commits

...

196 Commits

Author SHA1 Message Date
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
github-actions[bot]
f2687dc1bb 📝 Update release notes
[skip ci]
2026-01-02 06:47:25 +00:00
github-actions[bot]
862c3f4f94 📝 Update release notes
[skip ci]
2026-01-02 06:46:59 +00:00
Sebastián Ramírez
052d6e86c2 👥 Update FastAPI People - Sponsors (#14626)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-02 07:46:57 +01:00
Sebastián Ramírez
31c7ffcdfe 👥 Update FastAPI GitHub topic repositories (#14630)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-02 07:46:34 +01:00
github-actions[bot]
6854be9ebc 📝 Update release notes
[skip ci]
2026-01-02 06:40:39 +00:00
Sebastián Ramírez
258deb925d 👥 Update FastAPI People - Contributors and Translators (#14625)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-01-02 07:40:15 +01:00
github-actions[bot]
53d2453d1a 📝 Update release notes
[skip ci]
2025-12-29 18:54:43 +00:00
Sebastián Ramírez
d9b7b65b81 🌐 Update translation prompts (#14619) 2025-12-29 18:54:20 +00:00
github-actions[bot]
9ed5f246ed 📝 Update release notes
[skip ci]
2025-12-29 12:38:35 +00:00
Sebastián Ramírez
edf7995775 🔧 Add LLM prompt file for Turkish, generated from the existing translations (#14547) 2025-12-29 13:38:11 +01:00
github-actions[bot]
47391ea8fb 📝 Update release notes
[skip ci]
2025-12-27 19:06:15 +00:00
Sebastián Ramírez
3b1b4f034b 🔨 Update LLM translation script to guide reviewers to change the prompt (#14614) 2025-12-27 19:05:53 +00:00
github-actions[bot]
f362fdc234 📝 Update release notes
[skip ci]
2025-12-27 18:51:39 +00:00
github-actions[bot]
4ce34686d9 📝 Update release notes
[skip ci]
2025-12-27 18:51:18 +00:00
Sebastián Ramírez
dbe83f3919 🔧 Add LLM prompt file for Traditional Chinese, generated from the existing translations (#14550)
Co-authored-by: W. H. Wang <mattwang44@gmail.com>
2025-12-27 19:49:46 +01:00
github-actions[bot]
13743e115a 📝 Update release notes
[skip ci]
2025-12-27 18:49:09 +00:00
Sebastián Ramírez
52842fb8d3 🔧 Add LLM prompt file for Simplified Chinese, generated from the existing translations (#14549)
Co-authored-by: 史雲昔 (Vincy SHI) <vincy@vincy1230.net>
2025-12-27 19:49:08 +01:00
Sebastián Ramírez
4d4fb28f9f 👷 Do not run translations on cron while finishing updating existing languages (#14613) 2025-12-27 18:48:45 +00:00
github-actions[bot]
a1735d6d11 📝 Update release notes
[skip ci]
2025-12-27 18:31:59 +00:00
Sebastián Ramírez
1b42639296 🔥 Remove test variants for Pydantic v1 in test_request_params (#14612) 2025-12-27 19:31:34 +01:00
github-actions[bot]
ded035a421 📝 Update release notes
[skip ci]
2025-12-27 18:19:33 +00:00
Sebastián Ramírez
44c849c4fc 🔥 Remove Pydantic v1 specific test variants (#14611) 2025-12-27 19:19:10 +01:00
Sebastián Ramírez
8322a4445a 🔖 Release version 0.128.0 2025-12-27 16:19:50 +01:00
github-actions[bot]
4b2cfcfd34 📝 Update release notes
[skip ci]
2025-12-27 12:55:22 +00:00
Sebastián Ramírez
e300630551 Drop support for pydantic.v1 (#14609) 2025-12-27 13:54:56 +01:00
github-actions[bot]
1b3bea8b6b 📝 Update release notes
[skip ci]
2025-12-26 20:40:51 +00:00
Sebastián Ramírez
34e884156f Run performance tests only on Pydantic v2 (#14608) 2025-12-26 20:40:26 +00:00
Sebastián Ramírez
cd90c78391 🔖 Release version 0.127.1 2025-12-26 14:02:41 +01:00
github-actions[bot]
93f4dfd88b 📝 Update release notes
[skip ci]
2025-12-26 12:46:00 +00:00
Sebastián Ramírez
535b5daa31 🔊 Add a custom FastAPIDeprecationWarning (#14605) 2025-12-26 12:45:20 +00:00
github-actions[bot]
6b53786f62 📝 Update release notes
[skip ci]
2025-12-26 11:37:18 +00:00
Sebastián Ramírez
d98f4eb56e 🔧 Update pre-commit to use local Ruff instead of hook (#14604) 2025-12-26 11:36:58 +00:00
github-actions[bot]
8cefc4b7cc 📝 Update release notes
[skip ci]
2025-12-26 10:43:27 +00:00
Motov Yurii
3063ada72f Add missing tests for code examples (#14569)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Nils-Hero Lindemann <nilsherolindemann@proton.me>
2025-12-26 11:43:02 +01:00
github-actions[bot]
5eb8d6ed8a 📝 Update release notes
[skip ci]
2025-12-26 09:40:18 +00:00
Nils-Hero Lindemann
7c751a2e1c 🌐 Update translations for de (update-outdated) (#14602)
* Sync with #14600

* A few changes

The LLM suggested a few changes when retranslating the document, these are the good ones.

I also added a term to the llm prompt, the LLM instead used just "Abdeckung", which is too broad in this context.
2025-12-26 10:39:53 +01:00
github-actions[bot]
55b556a7d1 📝 Update release notes
[skip ci]
2025-12-26 08:54:23 +00:00
Motov Yurii
a4d04c9b7e 👷 Remove lint job from test CI workflow (#14593)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
2025-12-26 09:53:59 +01:00
github-actions[bot]
23caa2709b 📝 Update release notes
[skip ci]
2025-12-25 11:02:01 +00:00
Sebastián Ramírez
c264467efe 📝 Add documentary to website (#14600) 2025-12-25 11:01:37 +00:00
github-actions[bot]
2b212ddd76 📝 Update release notes
[skip ci]
2025-12-24 10:28:45 +00:00
Nils-Hero Lindemann
7203e860b3 🌐 Update translations for de (update-outdated) (#14581)
* Sync with #14575 (Drop support for Pydantic v1)

* Add a word and fix a typo

Found while syncing.
2025-12-24 11:28:19 +01:00
github-actions[bot]
e55f223b46 📝 Update release notes
[skip ci]
2025-12-23 11:17:37 +00:00
Sebastián Ramírez
a329baaa54 👷 Update secrets check (#14592) 2025-12-23 11:17:16 +00:00
github-actions[bot]
a7a0aee984 📝 Update release notes
[skip ci]
2025-12-21 17:52:08 +00:00
Sebastián Ramírez
6539b80d9f 👷 Run CodSpeed tests in parallel to other tests to speed up CI (#14586) 2025-12-21 18:51:45 +01:00
github-actions[bot]
e1bd9f3e33 📝 Update release notes
[skip ci]
2025-12-21 17:40:41 +00:00
Sebastián Ramírez
b9b2793bda 🔨 Update scripts and pre-commit to autofix files (#14585) 2025-12-21 17:40:17 +00:00
Sebastián Ramírez
c4a1ab5036 🔖 Release version 0.127.0 2025-12-21 17:45:43 +01:00
github-actions[bot]
22c7200ebb 📝 Update release notes
[skip ci]
2025-12-21 16:44:32 +00:00
Sebastián Ramírez
6e42bcd8ce 🔊 Add deprecation warnings when using pydantic.v1 (#14583) 2025-12-21 17:44:10 +01:00
github-actions[bot]
6513d4daa1 📝 Update release notes
[skip ci]
2025-12-21 08:06:42 +00:00
Sebastián Ramírez
1d93d531bc ⬆️ Upgrade OpenAI model for translations to gpt-5.2 (#14579) 2025-12-21 08:06:22 +00:00
github-actions[bot]
c2c1cc8aec 📝 Update release notes
[skip ci]
2025-12-20 17:32:31 +00:00
Sebastián Ramírez
5289259275 🔧 Add LLM prompt file for Korean, generated from the existing translations (#14546)
Co-authored-by: hy.lee <rurouni24@gmail.com>
2025-12-20 18:32:05 +01:00
github-actions[bot]
5783910d0c 📝 Update release notes
[skip ci]
2025-12-20 17:31:11 +00:00
Sebastián Ramírez
026b43e5d3 🔧 Add LLM prompt file for Japanese, generated from the existing translations (#14545)
Co-authored-by: Maruo.S <raspi-maru2004@outlook.jp>
2025-12-20 18:30:52 +01:00
827 changed files with 44452 additions and 29608 deletions

View File

@@ -8,7 +8,7 @@ updates:
commit-message:
prefix:
# Python
- package-ecosystem: "pip"
- package-ecosystem: "uv"
directory: "/"
schedule:
interval: "monthly"

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

@@ -8,9 +8,6 @@ on:
- opened
- synchronize
env:
UV_SYSTEM_PYTHON: 1
jobs:
changes:
runs-on: ubuntu-latest
@@ -31,8 +28,8 @@ jobs:
- README.md
- docs/**
- docs_src/**
- requirements-docs.txt
- pyproject.toml
- uv.lock
- mkdocs.yml
- mkdocs.env.yml
- .github/workflows/build-docs.yml
@@ -49,23 +46,20 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.11"
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
version: "0.4.15"
enable-cache: true
cache-dependency-glob: |
requirements**.txt
pyproject.toml
uv.lock
- name: Install docs extras
run: uv pip install -r requirements-docs.txt
- name: Verify Docs
run: python ./scripts/docs.py verify-docs
run: uv sync --locked --no-dev --group docs
- name: Export Language Codes
id: show-langs
run: |
echo "langs=$(python ./scripts/docs.py langs-json)" >> $GITHUB_OUTPUT
echo "langs=$(uv run ./scripts/docs.py langs-json)" >> $GITHUB_OUTPUT
build-docs:
needs:
@@ -85,26 +79,25 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.11"
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
version: "0.4.15"
enable-cache: true
cache-dependency-glob: |
requirements**.txt
pyproject.toml
uv.lock
- name: Install docs extras
run: uv pip install -r requirements-docs.txt
run: uv sync --locked --no-dev --group docs
- name: Update Languages
run: python ./scripts/docs.py update-languages
- uses: actions/cache@v4
run: uv run ./scripts/docs.py update-languages
- uses: actions/cache@v5
with:
key: mkdocs-cards-${{ matrix.lang }}-${{ github.ref }}
path: docs/${{ matrix.lang }}/.cache
- name: Build Docs
run: python ./scripts/docs.py build-lang ${{ matrix.lang }}
- uses: actions/upload-artifact@v5
run: uv run ./scripts/docs.py build-lang ${{ matrix.lang }}
- uses: actions/upload-artifact@v6
with:
name: docs-site-${{ matrix.lang }}
path: ./site/**

View File

@@ -10,9 +10,6 @@ on:
required: false
default: "false"
env:
UV_SYSTEM_PYTHON: 1
jobs:
job:
if: github.repository_owner == 'fastapi'
@@ -28,17 +25,16 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.11"
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
version: "0.4.15"
enable-cache: true
cache-dependency-glob: |
requirements**.txt
pyproject.toml
uv.lock
- name: Install Dependencies
run: uv pip install -r requirements-github-actions.txt
run: uv sync --locked --no-dev --group github-actions
# Allow debugging with tmate
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
@@ -48,6 +44,6 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}
- name: FastAPI People Contributors
run: python ./scripts/contributors.py
run: uv run ./scripts/contributors.py
env:
GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}

View File

@@ -12,9 +12,6 @@ permissions:
pull-requests: write
statuses: write
env:
UV_SYSTEM_PYTHON: 1
jobs:
deploy-docs:
runs-on: ubuntu-latest
@@ -27,19 +24,18 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.11"
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
version: "0.4.15"
enable-cache: true
cache-dependency-glob: |
requirements**.txt
pyproject.toml
uv.lock
- name: Install GitHub Actions dependencies
run: uv pip install -r requirements-github-actions.txt
run: uv sync --locked --no-dev --group github-actions
- name: Deploy Docs Status Pending
run: python ./scripts/deploy_docs_status.py
run: uv run ./scripts/deploy_docs_status.py
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COMMIT_SHA: ${{ github.event.workflow_run.head_sha }}
@@ -49,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-*
@@ -70,14 +66,14 @@ jobs:
command: pages deploy ./site --project-name=${{ env.PROJECT_NAME }} --branch=${{ env.BRANCH }}
- name: Deploy Docs Status Error
if: failure()
run: python ./scripts/deploy_docs_status.py
run: uv run ./scripts/deploy_docs_status.py
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COMMIT_SHA: ${{ github.event.workflow_run.head_sha }}
RUN_ID: ${{ github.run_id }}
STATE: "error"
- name: Comment Deploy
run: python ./scripts/deploy_docs_status.py
run: uv run ./scripts/deploy_docs_status.py
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DEPLOY_URL: ${{ steps.deploy.outputs.deployment-url }}

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

@@ -8,9 +8,6 @@ on:
permissions:
pull-requests: write
env:
UV_SYSTEM_PYTHON: 1
jobs:
label-approved:
if: github.repository_owner == 'fastapi'
@@ -24,19 +21,18 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.11"
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
version: "0.4.15"
enable-cache: true
cache-dependency-glob: |
requirements**.txt
pyproject.toml
uv.lock
- name: Install GitHub Actions dependencies
run: uv pip install -r requirements-github-actions.txt
run: uv sync --locked --no-dev --group github-actions
- name: Label Approved
run: python ./scripts/label_approved.py
run: uv run ./scripts/label_approved.py
env:
TOKEN: ${{ secrets.GITHUB_TOKEN }}
CONFIG: >

View File

@@ -15,9 +15,6 @@ on:
required: false
default: 'false'
env:
UV_SYSTEM_PYTHON: 1
jobs:
job:
runs-on: ubuntu-latest
@@ -32,17 +29,16 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.11"
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
version: "0.4.15"
enable-cache: true
cache-dependency-glob: |
requirements**.txt
pyproject.toml
uv.lock
- name: Install Dependencies
run: uv pip install -r requirements-github-actions.txt
run: uv sync --locked --no-dev --group github-actions
# Allow debugging with tmate
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
@@ -52,7 +48,7 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Notify Translations
run: python ./scripts/notify_translations.py
run: uv run ./scripts/notify_translations.py
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NUMBER: ${{ github.event.inputs.number || null }}

View File

@@ -10,9 +10,6 @@ on:
required: false
default: "false"
env:
UV_SYSTEM_PYTHON: 1
jobs:
job:
if: github.repository_owner == 'fastapi'
@@ -28,17 +25,16 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.11"
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
version: "0.4.15"
enable-cache: true
cache-dependency-glob: |
requirements**.txt
pyproject.toml
uv.lock
- name: Install Dependencies
run: uv pip install -r requirements-github-actions.txt
run: uv sync --locked --no-dev --group github-actions
# Allow debugging with tmate
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
@@ -48,7 +44,7 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.FASTAPI_PEOPLE }}
- name: FastAPI People Experts
run: python ./scripts/people.py
run: uv run ./scripts/people.py
env:
GITHUB_TOKEN: ${{ secrets.FASTAPI_PEOPLE }}
SLEEP_INTERVAL: ${{ vars.PEOPLE_SLEEP_INTERVAL }}

View File

@@ -7,7 +7,8 @@ on:
- synchronize
env:
IS_FORK: ${{ github.event.pull_request.head.repo.full_name != github.repository }}
# Forks and Dependabot don't have access to secrets
HAS_SECRETS: ${{ secrets.PRE_COMMIT != '' }}
jobs:
pre-commit:
@@ -19,7 +20,7 @@ jobs:
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v5
name: Checkout PR for own repo
if: env.IS_FORK == 'false'
if: env.HAS_SECRETS == 'true'
with:
# To be able to commit it needs to fetch the head of the branch, not the
# merge commit
@@ -31,7 +32,7 @@ jobs:
# pre-commit lite ci needs the default checkout configs to work
- uses: actions/checkout@v5
name: Checkout PR for fork
if: env.IS_FORK == 'true'
if: env.HAS_SECRETS == 'false'
with:
# To be able to commit it needs the head branch of the PR, the remote one
ref: ${{ github.event.pull_request.head.sha }}
@@ -39,24 +40,21 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.14"
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
cache-dependency-glob: |
requirements**.txt
pyproject.toml
uv.lock
- name: Install Dependencies
run: |
uv venv
uv pip install -r requirements.txt
run: uv sync --locked --extra all
- name: Run prek - pre-commit
id: precommit
run: uvx prek run --from-ref origin/${GITHUB_BASE_REF} --to-ref HEAD --show-diff-on-failure
continue-on-error: true
- name: Commit and push changes
if: env.IS_FORK == 'false'
if: env.HAS_SECRETS == 'true'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
@@ -68,7 +66,7 @@ jobs:
git push
fi
- uses: pre-commit-ci/lite-action@v1.1.0
if: env.IS_FORK == 'true'
if: env.HAS_SECRETS == 'false'
with:
msg: 🎨 Auto format
- name: Error out on pre-commit errors

View File

@@ -15,6 +15,7 @@ jobs:
- fastapi-slim
permissions:
id-token: write
contents: read
steps:
- name: Dump GitHub context
env:
@@ -24,19 +25,15 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.10"
python-version-file: ".python-version"
# Issue ref: https://github.com/actions/setup-python/issues/436
# cache: "pip"
# cache-dependency-path: pyproject.toml
- name: Install build dependencies
run: pip install build
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Build distribution
run: uv build
env:
TIANGOLO_BUILD_PACKAGE: ${{ matrix.package }}
run: python -m build
- name: Publish
uses: pypa/gh-action-pypi-publish@v1.13.0
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
run: uv publish

View File

@@ -8,9 +8,6 @@ on:
permissions:
statuses: write
env:
UV_SYSTEM_PYTHON: 1
jobs:
smokeshow:
runs-on: ubuntu-latest
@@ -23,15 +20,15 @@ jobs:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: '3.13'
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
cache-dependency-glob: |
requirements**.txt
pyproject.toml
- run: uv pip install -r requirements-github-actions.txt
- uses: actions/download-artifact@v6
uv.lock
- run: uv sync --locked --no-dev --group github-actions
- uses: actions/download-artifact@v7
with:
name: coverage-html
path: htmlcov
@@ -41,7 +38,7 @@ jobs:
- name: Upload coverage to Smokeshow
run: |
for i in 1 2 3 4 5; do
if smokeshow upload htmlcov; then
if uv run smokeshow upload htmlcov; then
echo "Smokeshow upload success!"
break
fi

View File

@@ -10,9 +10,6 @@ on:
required: false
default: "false"
env:
UV_SYSTEM_PYTHON: 1
jobs:
job:
if: github.repository_owner == 'fastapi'
@@ -28,17 +25,16 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.11"
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
version: "0.4.15"
enable-cache: true
cache-dependency-glob: |
requirements**.txt
pyproject.toml
uv.lock
- name: Install Dependencies
run: uv pip install -r requirements-github-actions.txt
run: uv sync --locked --no-dev --group github-actions
# Allow debugging with tmate
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
@@ -46,7 +42,7 @@ jobs:
with:
limit-access-to-actor: true
- name: FastAPI People Sponsors
run: python ./scripts/sponsors.py
run: uv run ./scripts/sponsors.py
env:
SPONSORS_TOKEN: ${{ secrets.SPONSORS_TOKEN }}
PR_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}

View File

@@ -26,7 +26,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.10"
python-version-file: ".python-version"
- name: Install build dependencies
run: pip install build
- name: Build source distribution
@@ -40,7 +40,7 @@ jobs:
- name: Install test dependencies
run: |
cd dist/fastapi*/
pip install -r requirements-tests.txt
pip install --group tests --editable .[all]
env:
TIANGOLO_BUILD_PACKAGE: ${{ matrix.package }}
- name: Run source distribution tests

View File

@@ -13,33 +13,38 @@ on:
- cron: "0 0 * * 1"
env:
UV_SYSTEM_PYTHON: 1
UV_NO_SYNC: true
jobs:
lint:
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:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.11"
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
cache-dependency-glob: |
requirements**.txt
pyproject.toml
- name: Install Dependencies
run: uv pip install -r requirements-tests.txt
- name: Lint
run: bash scripts/lint.sh
- 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 ]
@@ -54,15 +59,21 @@ jobs:
- os: windows-latest
python-version: "3.12"
coverage: coverage
# Ubuntu with 3.13 needs coverage for CodSpeed benchmarks
- os: ubuntu-latest
python-version: "3.13"
coverage: coverage
# Ubuntu with 3.13 needs coverage for CodSpeed benchmarks
- os: ubuntu-latest
python-version: "3.13"
coverage: coverage
codspeed: codspeed
- os: ubuntu-latest
python-version: "3.14"
coverage: coverage
fail-fast: false
runs-on: ${{ matrix.os }}
env:
UV_PYTHON: ${{ matrix.python-version }}
steps:
- name: Dump GitHub context
env:
@@ -76,39 +87,40 @@ jobs:
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
version: "0.4.15"
enable-cache: true
cache-dependency-glob: |
requirements**.txt
pyproject.toml
uv.lock
- name: Install Dependencies
run: uv pip install -r requirements-tests.txt
run: uv sync --locked --no-dev --group tests --extra all
- run: mkdir coverage
- name: Test
run: bash scripts/test.sh
if: matrix.codspeed != 'codspeed'
run: uv run bash scripts/test.sh
env:
COVERAGE_FILE: coverage/.coverage.${{ runner.os }}-py${{ matrix.python-version }}
CONTEXT: ${{ runner.os }}-py${{ matrix.python-version }}
- name: CodSpeed benchmarks
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.13'
if: matrix.codspeed == 'codspeed'
uses: CodSpeedHQ/action@v4
env:
COVERAGE_FILE: coverage/.coverage.${{ runner.os }}-py${{ matrix.python-version }}
CONTEXT: ${{ runner.os }}-py${{ matrix.python-version }}
with:
mode: simulation
run: coverage run -m pytest tests/ --codspeed
run: uv run 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
@@ -118,33 +130,32 @@ jobs:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: '3.11'
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
version: "0.4.15"
enable-cache: true
cache-dependency-glob: |
requirements**.txt
pyproject.toml
uv.lock
- name: Install Dependencies
run: uv pip install -r requirements-tests.txt
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
merge-multiple: true
- run: ls -la coverage
- run: coverage combine coverage
- run: coverage html --title "Coverage for ${{ github.sha }}"
- 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
include-hidden-files: true
- run: coverage report --fail-under=100
- run: uv run coverage report --fail-under=100
# https://github.com/marketplace/actions/alls-green#why
check: # This job does nothing and is only used for the branch protection
@@ -161,3 +172,4 @@ jobs:
uses: re-actors/alls-green@release/v1
with:
jobs: ${{ toJSON(needs) }}
allowed-skips: coverage-combine,test

View File

@@ -5,9 +5,6 @@ on:
- cron: "0 12 1 * *"
workflow_dispatch:
env:
UV_SYSTEM_PYTHON: 1
jobs:
topic-repos:
if: github.repository_owner == 'fastapi'
@@ -23,18 +20,17 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.11"
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
version: "0.4.15"
enable-cache: true
cache-dependency-glob: |
requirements**.txt
pyproject.toml
uv.lock
- name: Install GitHub Actions dependencies
run: uv pip install -r requirements-github-actions.txt
run: uv sync --locked --no-dev --group github-actions
- name: Update Topic Repos
run: python ./scripts/topic_repos.py
run: uv run ./scripts/topic_repos.py
env:
GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}

View File

@@ -1,8 +1,8 @@
name: Translate
on:
schedule:
- cron: "0 5 15 * *" # Run at 05:00 on the 15 of every month
# schedule:
# - cron: "0 5 15 * *" # Run at 05:00 on the 15 of every month
workflow_dispatch:
inputs:
@@ -30,9 +30,11 @@ on:
type: string
required: false
default: ""
env:
UV_SYSTEM_PYTHON: 1
commit_in_place:
description: Commit changes directly instead of making a PR
type: boolean
required: false
default: false
jobs:
langs:
@@ -45,20 +47,20 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.11"
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
cache-dependency-glob: |
requirements**.txt
pyproject.toml
uv.lock
- name: Install Dependencies
run: uv pip install -r requirements-github-actions.txt -r requirements-translations.txt
run: uv sync --locked --no-dev --group github-actions --group translations
- name: Export Language Codes
id: show-langs
run: |
echo "langs=$(python ./scripts/translate.py llm-translatable-json)" >> $GITHUB_OUTPUT
echo "commands=$(python ./scripts/translate.py commands-json)" >> $GITHUB_OUTPUT
echo "langs=$(uv run ./scripts/translate.py llm-translatable-json)" >> $GITHUB_OUTPUT
echo "commands=$(uv run ./scripts/translate.py commands-json)" >> $GITHUB_OUTPUT
env:
LANGUAGE: ${{ github.event.inputs.language }}
COMMAND: ${{ github.event.inputs.command }}
@@ -84,15 +86,15 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.11"
python-version-file: ".python-version"
- name: Setup uv
uses: astral-sh/setup-uv@v7
with:
cache-dependency-glob: |
requirements**.txt
pyproject.toml
uv.lock
- name: Install Dependencies
run: uv pip install -r requirements-github-actions.txt -r requirements-translations.txt
run: uv sync --locked --no-dev --group github-actions --group translations
# Allow debugging with tmate
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
@@ -104,11 +106,12 @@ jobs:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
- name: FastAPI Translate
run: |
python ./scripts/translate.py ${{ matrix.command }}
python ./scripts/translate.py make-pr
uv run ./scripts/translate.py ${{ matrix.command }}
uv run ./scripts/translate.py make-pr
env:
GITHUB_TOKEN: ${{ secrets.FASTAPI_TRANSLATIONS }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LANGUAGE: ${{ matrix.lang }}
EN_PATH: ${{ github.event.inputs.en_path }}
COMMAND: ${{ matrix.command }}
COMMIT_IN_PLACE: ${{ github.event.inputs.commit_in_place }}

3
.gitignore vendored
View File

@@ -29,7 +29,4 @@ archive.zip
# macOS
.DS_Store
# Ignore while the setup still depends on requirements.txt files
uv.lock
.codspeed

View File

@@ -6,25 +6,68 @@ repos:
hooks:
- id: check-added-large-files
args: ['--maxkb=750']
exclude: ^uv.lock$
- id: check-toml
- id: check-yaml
args:
- --unsafe
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.3
hooks:
- id: ruff
args:
- --fix
- id: ruff-format
- repo: local
hooks:
- id: local-script
- id: local-ruff-check
name: ruff check
entry: uv run ruff check --force-exclude --fix --exit-non-zero-on-fix
require_serial: true
language: unsupported
name: local script
types: [python]
- id: local-ruff-format
name: ruff format
entry: uv run ruff format --force-exclude --exit-non-zero-on-format
require_serial: true
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
entry: uv run ./scripts/docs.py add-permalinks-pages
args:
- --update-existing
files: ^docs/en/docs/.*\.md$
- id: generate-readme
language: unsupported
name: generate README.md from index.md
entry: uv run ./scripts/docs.py generate-readme
files: ^docs/en/docs/index\.md|docs/en/data/sponsors\.yml|scripts/docs\.py$
pass_filenames: false
- id: update-languages
language: unsupported
name: update languages
entry: uv run ./scripts/docs.py update-languages
files: ^docs/.*|scripts/docs\.py$
pass_filenames: false
- id: ensure-non-translated
language: unsupported
name: ensure non-translated files are not modified
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$

1
.python-version Normal file
View File

@@ -0,0 +1 @@
3.11

View File

@@ -120,6 +120,12 @@ The key features are:
---
## FastAPI mini documentary
There's a <a href="https://www.youtube.com/watch?v=mpR8ngthqiE" class="external-link" target="_blank">FastAPI mini documentary</a> released at the end of 2025, you can watch it online:
<a href="https://www.youtube.com/watch?v=mpR8ngthqiE" target="_blank"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini Documentary"></a>
## **Typer**, the FastAPI of CLIs
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
@@ -158,8 +164,6 @@ $ pip install "fastapi[standard]"
Create a file `main.py` with:
```Python
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@@ -171,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}
```
@@ -180,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()
@@ -194,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}
```
@@ -285,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
@@ -297,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("/")
@@ -306,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}

View File

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

View File

@@ -4,7 +4,7 @@ FastAPI basiert auf **Pydantic**, und ich habe Ihnen gezeigt, wie Sie Pydantic-M
Aber FastAPI unterstützt auf die gleiche Weise auch die Verwendung von <a href="https://docs.python.org/3/library/dataclasses.html" class="external-link" target="_blank">`dataclasses`</a>:
{* ../../docs_src/dataclasses/tutorial001_py310.py hl[1,6:11,18:19] *}
{* ../../docs_src/dataclasses_/tutorial001_py310.py hl[1,6:11,18:19] *}
Das ist dank **Pydantic** ebenfalls möglich, da es <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">`dataclasses` intern unterstützt</a>.
@@ -32,7 +32,7 @@ Wenn Sie jedoch eine Menge Datenklassen herumliegen haben, ist dies ein guter Tr
Sie können `dataclasses` auch im Parameter `response_model` verwenden:
{* ../../docs_src/dataclasses/tutorial002_py310.py hl[1,6:12,18] *}
{* ../../docs_src/dataclasses_/tutorial002_py310.py hl[1,6:12,18] *}
Die Datenklasse wird automatisch in eine Pydantic-Datenklasse konvertiert.
@@ -48,7 +48,7 @@ In einigen Fällen müssen Sie möglicherweise immer noch Pydantics Version von
In diesem Fall können Sie einfach die Standard-`dataclasses` durch `pydantic.dataclasses` ersetzen, was einen direkten Ersatz darstellt:
{* ../../docs_src/dataclasses/tutorial003_py310.py hl[1,4,7:10,13:16,22:24,27] *}
{* ../../docs_src/dataclasses_/tutorial003_py310.py hl[1,4,7:10,13:16,22:24,27] *}
1. Wir importieren `field` weiterhin von Standard-`dataclasses`.

View File

@@ -48,7 +48,7 @@ Sie können die verwendeten Zeilen aus dem Docstring einer *Pfadoperation-Funkti
Das Hinzufügen eines `\f` (ein maskiertes „Form Feed“-Zeichen) führt dazu, dass **FastAPI** die für OpenAPI verwendete Ausgabe an dieser Stelle abschneidet.
Sie wird nicht in der Dokumentation angezeigt, aber andere Tools (z. B. Sphinx) können den Rest verwenden.
Sie wird nicht in der Dokumentation angezeigt, aber andere Tools (wie z. B. Sphinx) können den Rest verwenden.
{* ../../docs_src/path_operation_advanced_configuration/tutorial004_py310.py hl[17:27] *}
@@ -153,48 +153,16 @@ Und Sie könnten dies auch tun, wenn der Datentyp im Request nicht JSON ist.
In der folgenden Anwendung verwenden wir beispielsweise weder die integrierte Funktionalität von FastAPI zum Extrahieren des JSON-Schemas aus Pydantic-Modellen noch die automatische Validierung für JSON. Tatsächlich deklarieren wir den Request-Content-Type als YAML und nicht als JSON:
//// tab | Pydantic v2
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
////
//// tab | Pydantic v1
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[15:20, 22] *}
////
/// info | Info
In Pydantic Version 1 hieß die Methode zum Abrufen des JSON-Schemas für ein Modell `Item.schema()`, in Pydantic Version 2 heißt die Methode `Item.model_json_schema()`.
///
Obwohl wir nicht die standardmäßig integrierte Funktionalität verwenden, verwenden wir dennoch ein Pydantic-Modell, um das JSON-Schema für die Daten, die wir in YAML empfangen möchten, manuell zu generieren.
Dann verwenden wir den Request direkt und extrahieren den Body als `bytes`. Das bedeutet, dass FastAPI nicht einmal versucht, den Request-Payload als JSON zu parsen.
Dann verwenden wir den Request direkt und extrahieren den Body als `bytes`. Das bedeutet, dass FastAPI nicht einmal versucht, die Request-Payload als JSON zu parsen.
Und dann parsen wir in unserem Code diesen YAML-Inhalt direkt und verwenden dann wieder dasselbe Pydantic-Modell, um den YAML-Inhalt zu validieren:
//// tab | Pydantic v2
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
////
//// tab | Pydantic v1
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[24:31] *}
////
/// info | Info
In Pydantic Version 1 war die Methode zum Parsen und Validieren eines Objekts `Item.parse_obj()`, in Pydantic Version 2 heißt die Methode `Item.model_validate()`.
///
/// tip | Tipp
Hier verwenden wir dasselbe Pydantic-Modell wieder.

View File

@@ -60,24 +60,8 @@ Auf die gleiche Weise wie bei Pydantic-Modellen deklarieren Sie Klassenattribute
Sie können dieselben Validierungs-Funktionen und -Tools verwenden, die Sie für Pydantic-Modelle verwenden, z. B. verschiedene Datentypen und zusätzliche Validierungen mit `Field()`.
//// tab | Pydantic v2
{* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *}
////
//// tab | Pydantic v1
/// info | Info
In Pydantic v1 würden Sie `BaseSettings` direkt von `pydantic` statt von `pydantic_settings` importieren.
///
{* ../../docs_src/settings/tutorial001_pv1_py39.py hl[2,5:8,11] *}
////
/// tip | Tipp
Für ein schnelles Copy-and-paste verwenden Sie nicht dieses Beispiel, sondern das letzte unten.
@@ -215,8 +199,6 @@ APP_NAME="ChimichangApp"
Und dann aktualisieren Sie Ihre `config.py` mit:
//// tab | Pydantic v2
{* ../../docs_src/settings/app03_an_py39/config.py hl[9] *}
/// tip | Tipp
@@ -225,26 +207,6 @@ Das Attribut `model_config` wird nur für die Pydantic-Konfiguration verwendet.
///
////
//// tab | Pydantic v1
{* ../../docs_src/settings/app03_an_py39/config_pv1.py hl[9:10] *}
/// tip | Tipp
Die Klasse `Config` wird nur für die Pydantic-Konfiguration verwendet. Weitere Informationen finden Sie unter <a href="https://docs.pydantic.dev/1.10/usage/model_config/" class="external-link" target="_blank">Pydantic Model Config</a>.
///
////
/// info | Info
In Pydantic Version 1 erfolgte die Konfiguration in einer internen Klasse `Config`, in Pydantic Version 2 erfolgt sie in einem Attribut `model_config`. Dieses Attribut akzeptiert ein <abbr title="Dictionary Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr>. Um automatische Codevervollständigung und Inline-Fehlerberichte zu erhalten, können Sie `SettingsConfigDict` importieren und verwenden, um dieses `dict` zu definieren.
///
Hier definieren wir die Konfiguration `env_file` innerhalb Ihrer Pydantic-`Settings`-Klasse und setzen den Wert auf den Dateinamen mit der dotenv-Datei, die wir verwenden möchten.
### Die `Settings` nur einmal laden mittels `lru_cache` { #creating-the-settings-only-once-with-lru-cache }

View File

@@ -35,7 +35,7 @@ Abhängig von Ihrem Anwendungsfall könnten Sie eine andere Bibliothek vorziehen
Hier ist eine kleine Vorschau, wie Sie Strawberry mit FastAPI integrieren können:
{* ../../docs_src/graphql/tutorial001_py39.py hl[3,22,25] *}
{* ../../docs_src/graphql_/tutorial001_py39.py hl[3,22,25] *}
Weitere Informationen zu Strawberry finden Sie in der <a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry-Dokumentation</a>.

View File

@@ -2,21 +2,23 @@
Wenn Sie eine ältere FastAPI-App haben, nutzen Sie möglicherweise Pydantic Version 1.
FastAPI unterstützt seit Version 0.100.0 sowohl Pydantic v1 als auch v2.
FastAPI Version 0.100.0 unterstützte sowohl Pydantic v1 als auch v2. Es verwendete, was auch immer Sie installiert hatten.
Wenn Sie Pydantic v2 installiert hatten, wurde dieses verwendet. Wenn stattdessen Pydantic v1 installiert war, wurde jenes verwendet.
FastAPI Version 0.119.0 führte eine teilweise Unterstützung für Pydantic v1 innerhalb von Pydantic v2 (als `pydantic.v1`) ein, um die Migration zu v2 zu erleichtern.
Pydantic v1 ist jetzt deprecatet und die Unterstützung dafür wird in den nächsten Versionen von FastAPI entfernt, Sie sollten also zu **Pydantic v2 migrieren**. Auf diese Weise erhalten Sie die neuesten Features, Verbesserungen und Fixes.
FastAPI 0.126.0 entfernte die Unterstützung für Pydantic v1, während `pydantic.v1` noch eine Weile unterstützt wurde.
/// warning | Achtung
Außerdem hat das Pydantic-Team die Unterstützung für Pydantic v1 in den neuesten Python-Versionen eingestellt, beginnend mit **Python 3.14**.
Das Pydantic-Team hat die Unterstützung für Pydantic v1 in den neuesten Python-Versionen eingestellt, beginnend mit **Python 3.14**.
Dies schließt `pydantic.v1` ein, das unter Python 3.14 und höher nicht mehr unterstützt wird.
Wenn Sie die neuesten Features von Python nutzen möchten, müssen Sie sicherstellen, dass Sie Pydantic v2 verwenden.
///
Wenn Sie eine ältere FastAPI-App mit Pydantic v1 haben, zeige ich Ihnen hier, wie Sie sie zu Pydantic v2 migrieren, und die **neuen Features in FastAPI 0.119.0**, die Ihnen bei einer schrittweisen Migration helfen.
Wenn Sie eine ältere FastAPI-App mit Pydantic v1 haben, zeige ich Ihnen hier, wie Sie sie zu Pydantic v2 migrieren, und die **Features in FastAPI 0.119.0**, die Ihnen bei einer schrittweisen Migration helfen.
## Offizieller Leitfaden { #official-guide }
@@ -44,7 +46,7 @@ Danach können Sie die Tests ausführen und prüfen, ob alles funktioniert. Fall
## Pydantic v1 in v2 { #pydantic-v1-in-v2 }
Pydantic v2 enthält alles aus Pydantic v1 als Untermodul `pydantic.v1`.
Pydantic v2 enthält alles aus Pydantic v1 als Untermodul `pydantic.v1`. Dies wird aber in Versionen oberhalb von Python 3.13 nicht mehr unterstützt.
Das bedeutet, Sie können die neueste Version von Pydantic v2 installieren und die alten Pydanticv1Komponenten aus diesem Untermodul importieren und verwenden, als hätten Sie das alte Pydantic v1 installiert.

View File

@@ -1,6 +1,6 @@
# Separate OpenAPI-Schemas für Eingabe und Ausgabe oder nicht { #separate-openapi-schemas-for-input-and-output-or-not }
Bei Verwendung von **Pydantic v2** ist die generierte OpenAPI etwas genauer und **korrekter** als zuvor. 😎
Seit der Veröffentlichung von **Pydantic v2** ist die generierte OpenAPI etwas genauer und **korrekter** als zuvor. 😎
Tatsächlich gibt es in einigen Fällen sogar **zwei JSON-Schemas** in OpenAPI für dasselbe Pydantic-Modell, für Eingabe und Ausgabe, je nachdem, ob sie **Defaultwerte** haben.
@@ -100,5 +100,3 @@ Und jetzt wird es ein einziges Schema für die Eingabe und Ausgabe des Modells g
<div class="screenshot">
<img src="/img/tutorial/separate-openapi-schemas/image05.png">
</div>
Dies ist das gleiche Verhalten wie in Pydantic v1. 🤓

View File

@@ -117,6 +117,12 @@ Seine Schlüssel-Merkmale sind:
---
## FastAPI Mini-Dokumentarfilm { #fastapi-mini-documentary }
Es gibt einen <a href="https://www.youtube.com/watch?v=mpR8ngthqiE" class="external-link" target="_blank">FastAPI-Mini-Dokumentarfilm</a>, veröffentlicht Ende 2025, Sie können ihn online ansehen:
<a href="https://www.youtube.com/watch?v=mpR8ngthqiE" target="_blank"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini-Dokumentarfilm"></a>
## **Typer**, das FastAPI der CLIs { #typer-the-fastapi-of-clis }
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
@@ -233,7 +239,7 @@ INFO: Application startup complete.
</div>
<details markdown="1">
<summary>Was der Befehl <code>fastapi dev main.py</code> macht ...</summary>
<summary>Über den Befehl <code>fastapi dev main.py</code> ...</summary>
Der Befehl `fastapi dev` liest Ihre `main.py`-Datei, erkennt die **FastAPI**-App darin und startet einen Server mit <a href="https://www.uvicorn.dev" class="external-link" target="_blank">Uvicorn</a>.
@@ -276,7 +282,7 @@ Sie sehen die alternative automatische Dokumentation (bereitgestellt von <a href
![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
## Beispiel Aktualisierung { #example-upgrade }
## Beispielaktualisierung { #example-upgrade }
Ändern Sie jetzt die Datei `main.py`, um den <abbr title="Body Körper, Inhalt: Der eigentliche Inhalt einer Nachricht, nicht die Metadaten">Body</abbr> eines `PUT`-Requests zu empfangen.
@@ -326,7 +332,7 @@ Gehen Sie jetzt auf <a href="http://127.0.0.1:8000/docs" class="external-link" t
![Swagger UI Interaktion](https://fastapi.tiangolo.com/img/index/index-04-swagger-03.png)
* Klicken Sie dann auf den Button „Execute“, die Benutzeroberfläche wird mit Ihrer API kommunizieren, sendet die Parameter, holt die Ergebnisse und zeigt sie auf dem Bildschirm an:
* Klicken Sie dann auf den Button „Execute“, die Benutzeroberfläche wird mit Ihrer API kommunizieren, die Parameter senden, die Ergebnisse erhalten und sie auf dem Bildschirm anzeigen:
![Swagger UI Interaktion](https://fastapi.tiangolo.com/img/index/index-05-swagger-04.png)
@@ -439,7 +445,7 @@ Für ein vollständigeres Beispiel, mit weiteren Funktionen, siehe das <a href="
* Deklaration von **Parametern** von anderen verschiedenen Stellen wie: **Header**, **Cookies**, **Formularfelder** und **Dateien**.
* Wie man **Validierungs-Constraints** wie `maximum_length` oder `regex` setzt.
* Ein sehr leistungsfähiges und einfach zu bedienendes System für **<abbr title="Dependency Injection Einbringen von Abhängigkeiten: Auch bekannt als Komponenten, Ressourcen, Provider, Services, Injectables">Dependency Injection</abbr>**.
* Ein sehr leistungsfähiges und einfach zu bedienendes System für **<abbr title="auch bekannt als Komponenten, Ressourcen, Provider, Services, Injectables">Dependency Injection</abbr>**.
* Sicherheit und Authentifizierung, einschließlich Unterstützung für **OAuth2** mit **JWT-Tokens** und **HTTP Basic** Authentifizierung.
* Fortgeschrittenere (aber ebenso einfache) Techniken zur Deklaration **tief verschachtelter JSON-Modelle** (dank Pydantic).
* **GraphQL**-Integration mit <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> und anderen Bibliotheken.
@@ -452,7 +458,7 @@ Für ein vollständigeres Beispiel, mit weiteren Funktionen, siehe das <a href="
### Ihre App deployen (optional) { #deploy-your-app-optional }
Optional können Sie Ihre FastAPI-App in die <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a> deployen, treten Sie der Warteliste bei, falls noch nicht geschehen. 🚀
Optional können Sie Ihre FastAPI-App in die <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a> deployen, gehen Sie und treten Sie der Warteliste bei, falls noch nicht geschehen. 🚀
Wenn Sie bereits ein **FastAPI Cloud**-Konto haben (wir haben Sie von der Warteliste eingeladen 😉), können Sie Ihre Anwendung mit einem einzigen Befehl deployen.
@@ -494,7 +500,7 @@ Es vereinfacht den Prozess des **Erstellens**, **Deployens** und **Zugreifens**
Es bringt die gleiche **Developer-Experience** beim Erstellen von Apps mit FastAPI auch zum **Deployment** in der Cloud. 🎉
FastAPI Cloud ist der Hauptsponsor und Finanzierer der FastAPI and friends Open-Source-Projekte. ✨
FastAPI Cloud ist der Hauptsponsor und Finanzierer der *FastAPI and friends* Open-Source-Projekte. ✨
#### Bei anderen Cloudanbietern deployen { #deploy-to-other-cloud-providers }

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

@@ -50,14 +50,6 @@ Wenn Sie Teil-Aktualisierungen entgegennehmen, ist der `exclude_unset`-Parameter
Wie in `item.model_dump(exclude_unset=True)`.
/// info | Info
In Pydantic v1 hieß diese Methode `.dict()`, in Pydantic v2 wurde sie <abbr title="veraltet, obsolet: Es soll nicht mehr verwendet werden">deprecatet</abbr> (aber immer noch unterstützt) und in `.model_dump()` umbenannt.
Die Beispiele hier verwenden `.dict()` für die Kompatibilität mit Pydantic v1, Sie sollten jedoch stattdessen `.model_dump()` verwenden, wenn Sie Pydantic v2 verwenden können.
///
Das wird ein <abbr title="Dictionary Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr> erstellen, mit nur den Daten, die gesetzt wurden, als das `item`-Modell erstellt wurde, Defaultwerte ausgeschlossen.
Sie können das verwenden, um ein `dict` zu erstellen, das nur die (im <abbr title="Request Anfrage: Daten, die der Client zum Server sendet">Request</abbr>) gesendeten Daten enthält, ohne Defaultwerte:
@@ -68,14 +60,6 @@ Sie können das verwenden, um ein `dict` zu erstellen, das nur die (im <abbr tit
Jetzt können Sie eine Kopie des existierenden Modells mittels `.model_copy()` erstellen, wobei Sie dem `update`-Parameter ein `dict` mit den zu ändernden Daten übergeben.
/// info | Info
In Pydantic v1 hieß diese Methode `.copy()`, in Pydantic v2 wurde sie <abbr title="veraltet, obsolet: Es soll nicht mehr verwendet werden">deprecatet</abbr> (aber immer noch unterstützt) und in `.model_copy()` umbenannt.
Die Beispiele hier verwenden `.copy()` für die Kompatibilität mit Pydantic v1, Sie sollten jedoch stattdessen `.model_copy()` verwenden, wenn Sie Pydantic v2 verwenden können.
///
Wie in `stored_item_model.model_copy(update=update_data)`:
{* ../../docs_src/body_updates/tutorial002_py310.py hl[33] *}

View File

@@ -127,14 +127,6 @@ Innerhalb der Funktion können Sie alle Attribute des Modellobjekts direkt verwe
{* ../../docs_src/body/tutorial002_py310.py *}
/// info | Info
In Pydantic v1 hieß die Methode `.dict()`, sie wurde in Pydantic v2 deprecatet (aber weiterhin unterstützt) und in `.model_dump()` umbenannt.
Die Beispiele hier verwenden `.dict()` zur Kompatibilität mit Pydantic v1, aber Sie sollten stattdessen `.model_dump()` verwenden, wenn Sie Pydantic v2 nutzen können.
///
## Requestbody- + Pfad-Parameter { #request-body-path-parameters }
Sie können Pfad-Parameter und den Requestbody gleichzeitig deklarieren.

View File

@@ -22,21 +22,13 @@ Hier ist eine allgemeine Idee, wie die Modelle mit ihren Passwortfeldern aussehe
{* ../../docs_src/extra_models/tutorial001_py310.py hl[7,9,14,20,22,27:28,31:33,38:39] *}
/// info | Info
### Über `**user_in.model_dump()` { #about-user-in-model-dump }
In Pydantic v1 hieß die Methode `.dict()`, in Pydantic v2 wurde sie <abbr title="veraltet, obsolet: Es soll nicht mehr verwendet werden">deprecatet</abbr> (aber weiterhin unterstützt) und in `.model_dump()` umbenannt.
Die Beispiele hier verwenden `.dict()` für die Kompatibilität mit Pydantic v1, aber Sie sollten `.model_dump()` verwenden, wenn Sie Pydantic v2 verwenden können.
///
### Über `**user_in.dict()` { #about-user-in-dict }
#### Die `.dict()`-Methode von Pydantic { #pydantics-dict }
#### Pydantics `.model_dump()` { #pydantics-model-dump }
`user_in` ist ein Pydantic-Modell der Klasse `UserIn`.
Pydantic-Modelle haben eine `.dict()`-Methode, die ein <abbr title="Dictionary Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr> mit den Daten des Modells zurückgibt.
Pydantic-Modelle haben eine `.model_dump()`-Methode, die ein <abbr title="Dictionary Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr> mit den Daten des Modells zurückgibt.
Wenn wir also ein Pydantic-Objekt `user_in` erstellen, etwa so:
@@ -47,7 +39,7 @@ user_in = UserIn(username="john", password="secret", email="john.doe@example.com
und dann aufrufen:
```Python
user_dict = user_in.dict()
user_dict = user_in.model_dump()
```
haben wir jetzt ein `dict` mit den Daten in der Variablen `user_dict` (es ist ein `dict` statt eines Pydantic-Modellobjekts).
@@ -103,20 +95,20 @@ UserInDB(
#### Ein Pydantic-Modell aus dem Inhalt eines anderen { #a-pydantic-model-from-the-contents-of-another }
Da wir im obigen Beispiel `user_dict` von `user_in.dict()` bekommen haben, wäre dieser Code:
Da wir im obigen Beispiel `user_dict` von `user_in.model_dump()` bekommen haben, wäre dieser Code:
```Python
user_dict = user_in.dict()
user_dict = user_in.model_dump()
UserInDB(**user_dict)
```
gleichwertig zu:
```Python
UserInDB(**user_in.dict())
UserInDB(**user_in.model_dump())
```
... weil `user_in.dict()` ein `dict` ist, und dann lassen wir Python es „entpacken“, indem wir es an `UserInDB` mit vorangestelltem `**` übergeben.
... weil `user_in.model_dump()` ein `dict` ist, und dann lassen wir Python es „entpacken“, indem wir es an `UserInDB` mit vorangestelltem `**` übergeben.
Auf diese Weise erhalten wir ein Pydantic-Modell aus den Daten eines anderen Pydantic-Modells.
@@ -125,7 +117,7 @@ Auf diese Weise erhalten wir ein Pydantic-Modell aus den Daten eines anderen Pyd
Und dann fügen wir das zusätzliche Schlüsselwort-Argument `hashed_password=hashed_password` hinzu, wie in:
```Python
UserInDB(**user_in.dict(), hashed_password=hashed_password)
UserInDB(**user_in.model_dump(), hashed_password=hashed_password)
```
... was so ist wie:
@@ -180,7 +172,6 @@ Wenn Sie eine <a href="https://docs.pydantic.dev/latest/concepts/types/#unions"
{* ../../docs_src/extra_models/tutorial003_py310.py hl[1,14:15,18:20,33] *}
### `Union` in Python 3.10 { #union-in-python-3-10 }
In diesem Beispiel übergeben wir `Union[PlaneItem, CarItem]` als Wert des Arguments `response_model`.
@@ -203,7 +194,6 @@ Dafür verwenden Sie Pythons Standard-`typing.List` (oder nur `list` in Python 3
{* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *}
## Response mit beliebigem `dict` { #response-with-arbitrary-dict }
Sie können auch eine Response deklarieren, die ein beliebiges `dict` zurückgibt, indem Sie nur die Typen der Schlüssel und Werte ohne ein Pydantic-Modell deklarieren.
@@ -214,7 +204,6 @@ In diesem Fall können Sie `typing.Dict` verwenden (oder nur `dict` in Python 3.
{* ../../docs_src/extra_models/tutorial005_py39.py hl[6] *}
## Zusammenfassung { #recap }
Verwenden Sie gerne mehrere Pydantic-Modelle und vererben Sie je nach Bedarf.

View File

@@ -205,20 +205,6 @@ Wenn Sie sich mit all diesen **„regulärer Ausdruck“**-Ideen verloren fühle
Aber nun wissen Sie, dass Sie sie in **FastAPI** immer dann verwenden können, wenn Sie sie brauchen.
### Pydantic v1 `regex` statt `pattern` { #pydantic-v1-regex-instead-of-pattern }
Vor Pydantic Version 2 und FastAPI 0.100.0, hieß der Parameter `regex` statt `pattern`, aber das ist jetzt obsolet.
Sie könnten immer noch Code sehen, der den alten Namen verwendet:
//// tab | Pydantic v1
{* ../../docs_src/query_params_str_validations/tutorial004_regex_an_py310.py hl[11] *}
////
Beachten Sie aber, dass das obsolet ist und auf den neuen Parameter `pattern` aktualisiert werden sollte. 🤓
## Defaultwerte { #default-values }
Natürlich können Sie Defaultwerte verwenden, die nicht `None` sind.

View File

@@ -252,20 +252,6 @@ Wenn Sie also den Artikel mit der ID `foo` bei der *Pfadoperation* anfragen, wir
/// info | Info
In Pydantic v1 hieß diese Methode `.dict()`, in Pydantic v2 wurde sie <abbr title="veraltet, obsolet: Es soll nicht mehr verwendet werden">deprecatet</abbr> (aber immer noch unterstützt) und in `.model_dump()` umbenannt.
Die Beispiele hier verwenden `.dict()` für die Kompatibilität mit Pydantic v1, Sie sollten jedoch stattdessen `.model_dump()` verwenden, wenn Sie Pydantic v2 verwenden können.
///
/// info | Info
FastAPI verwendet `.dict()` von Pydantic Modellen, <a href="https://docs.pydantic.dev/1.10/usage/exporting_models/#modeldict" class="external-link" target="_blank">mit dessen `exclude_unset`-Parameter</a>, um das zu erreichen.
///
/// info | Info
Sie können auch:
* `response_model_exclude_defaults=True`

View File

@@ -8,36 +8,14 @@ Hier sind mehrere Möglichkeiten, das zu tun.
Sie können `examples` („Beispiele“) für ein Pydantic-Modell deklarieren, welche dem generierten JSON-Schema hinzugefügt werden.
//// tab | Pydantic v2
{* ../../docs_src/schema_extra_example/tutorial001_py310.py hl[13:24] *}
////
//// tab | Pydantic v1
{* ../../docs_src/schema_extra_example/tutorial001_pv1_py310.py hl[13:23] *}
////
Diese zusätzlichen Informationen werden unverändert zum für dieses Modell ausgegebenen **JSON-Schema** hinzugefügt und in der API-Dokumentation verwendet.
//// tab | Pydantic v2
In Pydantic Version 2 würden Sie das Attribut `model_config` verwenden, das ein <abbr title="Dictionary Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr> akzeptiert, wie beschrieben in <a href="https://docs.pydantic.dev/latest/api/config/" class="external-link" target="_blank">Pydantic-Dokumentation: Configuration</a>.
Sie können das Attribut `model_config` verwenden, das ein <abbr title="Dictionary Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr> akzeptiert, wie beschrieben in <a href="https://docs.pydantic.dev/latest/api/config/" class="external-link" target="_blank">Pydantic-Dokumentation: Configuration</a>.
Sie können `json_schema_extra` setzen, mit einem `dict`, das alle zusätzlichen Daten enthält, die im generierten JSON-Schema angezeigt werden sollen, einschließlich `examples`.
////
//// tab | Pydantic v1
In Pydantic Version 1 würden Sie eine interne Klasse `Config` und `schema_extra` verwenden, wie beschrieben in <a href="https://docs.pydantic.dev/1.10/usage/schema/#schema-customization" class="external-link" target="_blank">Pydantic-Dokumentation: Schema customization</a>.
Sie können `schema_extra` setzen, mit einem `dict`, das alle zusätzlichen Daten enthält, die im generierten JSON-Schema angezeigt werden sollen, einschließlich `examples`.
////
/// tip | Tipp
Mit derselben Technik können Sie das JSON-Schema erweitern und Ihre eigenen benutzerdefinierten Zusatzinformationen hinzufügen.

View File

@@ -4,213 +4,197 @@ Translate to German (Deutsch).
Language code: de.
### Definitions
"hyphen"
The character «-»
Unicode U+002D (HYPHEN-MINUS)
Alternative names: hyphen, dash, minus sign
"dash"
The character «–»
Unicode U+2013 (EN DASH)
German name: Halbgeviertstrich
### Grammar to use when talking to the reader
Use the formal grammar (use «Sie» instead of «Du»).
Use the formal grammar (use `Sie` instead of `Du`).
### Quotes
1) Convert neutral double quotes («"») and English double typographic quotes («“» and «”») to German double typographic quotes («„» and «“»). Convert neutral single quotes («'») and English single typographic quotes («‘» and «’») to German single typographic quotes («‚» and «‘»). Do NOT convert «`"» to «„», do NOT convert «"`» to «“».
1) Convert neutral double quotes (`"`) to German double typographic quotes (`„` and `“`). Convert neutral single quotes (`'`) to German single typographic quotes (`` and ``).
Do NOT convert quotes in code snippets and code blocks to their German typographic equivalents.
Examples:
Source (English):
Source (English):
«««
"Hello world"
“Hello Universe”
"He said: 'Hello'"
“my name is Nils
`"__main__"`
`"items"`
»»»
```
"Hello world"
“Hello Universe”
"He said: 'Hello'"
“my name is Nils
`"__main__"`
`"items"`
```
Result (German):
«««
„Hallo Welt“
„Hallo Universum“
„Er sagte: Hallo
„Mein Name ist Nils
`"__main__"`
`"items"`
»»»
Result (German):
```
„Hallo Welt“
„Hallo Universum“
„Er sagte: Hallo
„Mein Name ist Nils
`"__main__"`
`"items"`
```
### Ellipsis
1) Make sure there is a space between an ellipsis and a word following or preceding the ellipsis.
- Make sure there is a space between an ellipsis and a word following or preceding the ellipsis.
Examples:
Source (English):
Source (English):
«««
...as we intended.
...this would work:
...etc.
others...
More to come...
»»»
```
...as we intended.
...this would work:
...etc.
others...
More to come...
```
Result (German):
Result (German):
«««
... wie wir es beabsichtigt hatten.
... das würde funktionieren:
... usw.
Andere ...
Später mehr ...
»»»
2) This does not apply in URLs, code blocks, and code snippets. Do not remove or add spaces there.
```
... wie wir es beabsichtigt hatten.
... das würde funktionieren:
... usw.
Andere ...
Später mehr ...
```
- This does not apply in URLs, code blocks, and code snippets. Do not remove or add spaces there.
### Headings
1) Translate headings using the infinite form.
- Translate headings using the infinite form.
Examples:
Source (English):
Source (English):
«««
## Create a Project { #create-a-project }
»»»
```
## Create a Project { #create-a-project }
```
Translate with (German):
Result (German):
«««
## Ein Projekt erstellen { #create-a-project }
»»»
```
## Ein Projekt erstellen { #create-a-project }
```
Do NOT translate with (German):
Do NOT translate with (German):
«««
## Erstellen Sie ein Projekt { #create-a-project }
»»»
```
## Erstellen Sie ein Projekt { #create-a-project }
```
Source (English):
Source (English):
«««
# Install Packages { #install-packages }
»»»
```
# Install Packages { #install-packages }
```
Translate with (German):
Translate with (German):
«««
# Pakete installieren { #install-packages }
»»»
```
# Pakete installieren { #install-packages }
```
Do NOT translate with (German):
Do NOT translate with (German):
«««
# Installieren Sie Pakete { #install-packages }
»»»
```
# Installieren Sie Pakete { #install-packages }
```
Source (English):
Source (English):
«««
### Run Your Program { #run-your-program }
»»»
```
### Run Your Program { #run-your-program }
```
Translate with (German):
Translate with (German):
«««
### Ihr Programm ausführen { #run-your-program }
»»»
```
### Ihr Programm ausführen { #run-your-program }
```
Do NOT translate with (German):
Do NOT translate with (German):
«««
### Führen Sie Ihr Programm aus { #run-your-program }
»»»
```
### Führen Sie Ihr Programm aus { #run-your-program }
```
2) Make sure that the translated part of the heading does not end with a period.
- Make sure that the translated part of the heading does not end with a period.
Example:
Source (English):
Source (English):
«««
## Another module with `APIRouter` { #another-module-with-apirouter }
»»»
```
## Another module with `APIRouter` { #another-module-with-apirouter }
```
Translate with (German):
Translate with (German):
«««
## Ein weiteres Modul mit `APIRouter` { #another-module-with-apirouter }
»»»
```
## Ein weiteres Modul mit `APIRouter` { #another-module-with-apirouter }
```
Do NOT translate with (German) notice the added period:
Do NOT translate with (German) notice the added period:
«««
## Ein weiteres Modul mit `APIRouter`. { #another-module-with-apirouter }
»»»
```
## Ein weiteres Modul mit `APIRouter`. { #another-module-with-apirouter }
```
3) Replace occurrences of literal « - » (a space followed by a hyphen followed by a space) with « » (a space followed by a dash followed by a space) in the translated part of the heading.
- Replace occurrences of literal ` - ` (a space followed by a hyphen followed by a space) with ` ` (a space followed by a dash followed by a space) in the translated part of the heading.
Example:
Source (English):
Source (English):
«««
# FastAPI in Containers - Docker { #fastapi-in-containers-docker }
»»»
```
# FastAPI in Containers - Docker { #fastapi-in-containers-docker }
```
Translate with (German) notice the dash:
Translate with (German) notice the dash:
«««
# FastAPI in Containern Docker { #fastapi-in-containers-docker }
»»»
```
# FastAPI in Containern Docker { #fastapi-in-containers-docker }
```
Do NOT translate with (German) notice the hyphen:
Do NOT translate with (German) notice the hyphen:
«««
# FastAPI in Containern - Docker { #fastapi-in-containers-docker }
»»»
```
# FastAPI in Containern - Docker { #fastapi-in-containers-docker }
```
3.1) Do not apply rule 3 when there is no space before or no space after the hyphen.
- Do not apply rule 3 when there is no space before or no space after the hyphen.
Example:
Source (English):
Source (English):
«««
## Type hints and annotations { #type-hints-and-annotations }
»»»
```
## Type hints and annotations { #type-hints-and-annotations }
```
Translate with (German) notice the hyphen:
Translate with (German) - notice the hyphen:
«««
## Typhinweise und -annotationen { #type-hints-and-annotations }
»»»
```
## Typhinweise und -annotationen { #type-hints-and-annotations }
```
Do NOT translate with (German) notice the dash:
Do NOT translate with (German) - notice the dash:
«««
## Typhinweise und annotationen { #type-hints-and-annotations }
»»»
```
## Typhinweise und annotationen { #type-hints-and-annotations }
```
3.2) Do not apply rule 3 to the untranslated part of the heading inside curly brackets, which you shall not translate.
- Do not modify the hyphens in the content in headers inside of curly braces, which you shall not translate.
### German instructions, when to use and when not to use hyphens in words (written in first person, which is you)
### German instructions, when to use and when not to use hyphens in words (written in first person, which is you).
In der Regel versuche ich so weit wie möglich Worte zusammenzuschreiben, also ohne Bindestrich, es sei denn, es ist Konkretesding-Klassevondingen, etwa «Pydantic-Modell» (aber: «Datenbankmodell»), «Python-Modul» (aber: «Standardmodul»). Ich setze auch einen Bindestrich, wenn er die gleichen Buchstaben verbindet, etwa «Enum-Member», «Cloud-Dienst», «Template-Engine». Oder wenn das Wort sonst einfach zu lang wird, etwa, «Performance-Optimierung». Oder um etwas visuell besser zu dokumentieren, etwa «Pfadoperation-Dekorator», «Pfadoperation-Funktion».
@@ -219,122 +203,122 @@ In der Regel versuche ich so weit wie möglich Worte zusammenzuschreiben, also o
Ich versuche nicht, alles einzudeutschen. Das bezieht sich besonders auf Begriffe aus dem Bereich der Programmierung. Ich wandele zwar korrekt in Großschreibung um und setze Bindestriche, wo notwendig, aber ansonsten lasse ich solch ein Wort unverändert. Beispielsweise wird aus dem englischen Wort «string» in der deutschen Übersetzung «String», aber nicht «Zeichenkette». Oder aus dem englischen Wort «request body» wird in der deutschen Übersetzung «Requestbody», aber nicht «Anfragekörper». Oder aus dem englischen «response» wird im Deutschen «Response», aber nicht «Antwort».
### List of English terms and their preferred German translations
Below is a list of English terms and their preferred German translations, separated by a colon («:»). Use these translations, do not use your own. If an existing translation does not use these terms, update it to use them. In the below list, a term or a translation may be followed by an explanation in brackets, which explains when to translate the term this way. If a translation is preceded by «NOT», then that means: do NOT use this translation for this term. English nouns, starting with the word «the», have the German genus «der», «die», «das» prepended to their German translation, to help you to grammatically decline them in the translation. They are given in singular case, unless they have «(plural)» attached, which means they are given in plural case. Verbs are given in the full infinitive starting with the word «to».
Below is a list of English terms and their preferred German translations, separated by a colon (:). Use these translations, do not use your own. If an existing translation does not use these terms, update it to use them. In the below list, a term or a translation may be followed by an explanation in brackets, which explains when to translate the term this way. If a translation is preceded by `NOT`, then that means: do NOT use this translation for this term. English nouns, starting with the word `the`, have the German genus `der`, `die`, `das` prepended to their German translation, to help you to grammatically decline them in the translation. They are given in singular case, unless they have `(plural)` attached, which means they are given in plural case. Verbs are given in the full infinitive starting with the word `to`.
* «/// check»: «/// check | Testen»
* «/// danger»: «/// danger | Gefahr»
* «/// info»: «/// info | Info»
* «/// note | Technical Details»: «/// note | Technische Details»
* «/// note»: «/// note | Hinweis»
* «/// tip»: «/// tip | Tipp»
* «/// warning»: «/// warning | Achtung»
* «you»: «Sie»
* «your»: «Ihr»
* «e.g»: «z. B.»
* «etc.»: «usw.»
* «ref»: «Ref.»
* «the Tutorial - User guide»: «das Tutorial Benutzerhandbuch»
* «the Advanced User Guide»: «das Handbuch für fortgeschrittene Benutzer»
* «the SQLModel docs»: «die SQLModel-Dokumentation»
* «the docs»: «die Dokumentation» (use singular case)
* «the env var»: «die Umgebungsvariable»
* «the `PATH` environment variable»: «die `PATH`-Umgebungsvariable»
* «the `PATH`»: «der `PATH`»
* «the `requirements.txt`»: «die `requirements.txt`»
* «the API Router»: «der API-Router»
* «the Authorization-Header»: «der Autorisierungsheader»
* «the `Authorization`-Header»: «der `Authorization`-Header»
* «the background task»: «der Hintergrundtask»
* «the button»: «der Button»
* «the cloud provider»: «der Cloudanbieter»
* «the CLI»: «Das CLI»
* «the command line interface»: «Das Kommandozeileninterface»
* «the default value»: «der Defaultwert»
* «the default value»: NOT «der Standardwert»
* «the default declaration»: «die Default-Deklaration»
* «the deployment»: «das Deployment»
* «the dict»: «das Dict»
* «the dictionary»: «das Dictionary»
* «the enumeration»: «die Enumeration»
* «the enum»: «das Enum»
* «the engine»: «die Engine»
* «the error response»: «die Error-Response»
* «the event»: «das Event»
* «the exception»: «die Exception»
* «the exception handler»: «der Exceptionhandler»
* «the form model»: «das Formularmodell»
* «the form body»: «der Formularbod
* «the header»: «der Header»
* «the headers» (plural): «die Header»
* «in headers» (plural): «in Header
* «the forwarded header»: «der Forwarded-Header»
* «the lifespan event»: «das Lifespan-Event»
* «the lock»: «der Lock»
* «the locking»: «das Locking»
* «the mobile application»: «die Mobile-Anwendung»
* «the model object»: «das Modellobjekt»
* «the mounting»: «das Mounten»
* «mounted»: «gemounte
* «the origin»: «das Origin»
* «the override»: «Die Überschreibung»
* «the parameter»: «der Parameter»
* «the parameters» (plural): «die Parameter»
* «the function parameter»: «der Funktionsparameter»
* «the default parameter»: «der Defaultparameter»
* «the body parameter»: «der Body-Parameter»
* «the request body parameter»: «der Requestbody-Parameter»
* «the path parameter»: «der Pfad-Parameter»
* «the query parameter»: «der Query-Parameter»
* «the cookie parameter»: «der Cookie-Parameter»
* «the header parameter»: «der Header-Parameter»
* «the form parameter»: «der Formular-Parameter»
* «the payload»: «die Payload»
* «the performance»: NOT «die Performance»
* «the query»: «die Query»
* «the recap»: «die Zusammenfassung»
* «the request» (what the client sends to the server): «der Request»
* «the request body»: «der Requestbody»
* «the request bodies» (plural): «die Requestbody
* «the response» (what the server sends back to the client): «die Response»
* «the return type»: «der Rückgabetyp»
* «the return value»: «der Rückgabewert»
* «the startup» (the event of the app): «der Startup»
* «the shutdown» (the event of the app): «der Shutdown»
* «the startup event»: «das Startup-Event»
* «the shutdown event»: «das Shutdown-Event»
* «the startup» (of the server): «das Hochfahren»
* «the startup» (the company): «das Startup»
* «the SDK»: «das SDK»
* «the tag»: «der Tag»
* «the type annotation»: «die Typannotation»
* «the type hint»: «der Typhinweis»
* «the wildcard»: «die Wildcard»
* «the worker class»: «die Workerklasse»
* «the worker class»: NOT «die Arbeiterklasse»
* «the worker process»: «der Workerprozess»
* «the worker process»: NOT «der Arbeiterprozess»
* «to commit»: «committen»
* «to deploy» (in the cloud): «deployen»
* «to modify»: «ändern»
* «to serve» (an application): «bereitstellen»
* «to serve» (a response): «ausliefern»
* «to serve»: NOT «bedienen»
* «to upgrade»: «aktualisieren»
* «to wrap»: «wrappen»
* «to wrap»: NOT «hüllen»
* «`foo` as a `type`»: «`foo` vom Typ `type`»
* «`foo` as a `type`»: «`foo`, ein `type`»
* «FastAPI's X»: «FastAPIs X»
* «Starlette's Y»: «Starlettes Y»
* «X is case-sensitive»: «Groß-/Klein­schrei­bung ist relevant in X»
* «X is case-insensitive»: «Groß-/Klein­schrei­bung ist nicht relevant in X»
* «standard Python»: «Standard-Python»
* «deprecated»: «deprecatet»
* /// check: /// check | Testen
* /// danger: /// danger | Gefahr
* /// info: /// info | Info
* /// note | Technical Details: /// note | Technische Details
* /// note: /// note | Hinweis
* /// tip: /// tip | Tipp
* /// warning: /// warning | Achtung
* you: Sie
* your: Ihr
* e.g: z. B.
* etc.: usw.
* ref: Ref.
* the Tutorial - User guide: das Tutorial Benutzerhandbuch
* the Advanced User Guide: das Handbuch für fortgeschrittene Benutzer
* the SQLModel docs: die SQLModel-Dokumentation
* the docs: die Dokumentation (use singular case)
* the env var: die Umgebungsvariable
* the `PATH` environment variable: die `PATH`-Umgebungsvariable
* the `PATH`: der `PATH`
* the `requirements.txt`: die `requirements.txt`
* the API Router: der API-Router
* the Authorization-Header: der Autorisierungsheader
* the `Authorization`-Header: der `Authorization`-Header
* the background task: der Hintergrundtask
* the button: der Button
* the cloud provider: der Cloudanbieter
* the CLI: Das CLI
* the coverage: Die Testabdeckung
* the command line interface: Das Kommandozeileninterface
* the default value: der Defaultwert
* the default value: NOT der Standardwert
* the default declaration: die Default-Deklaration
* the deployment: das Deployment
* the dict: das Dict
* the dictionary: das Dictionary
* the enumeration: die Enumeration
* the enum: das Enum
* the engine: die Engine
* the error response: die Error-Response
* the event: das Event
* the exception: die Exception
* the exception handler: der Exceptionhandler
* the form model: das Formularmodell
* the form body: der Formularbody
* the header: der Header
* the headers (plural): die Header
* in headers (plural): in Headern
* the forwarded header: der Forwarded-Header
* the lifespan event: das Lifespan-Event
* the lock: der Lock
* the locking: das Locking
* the mobile application: die Mobile-Anwendung
* the model object: das Modellobjekt
* the mounting: das Mounten
* mounted: gemountet
* the origin: das Origin
* the override: Die Überschreibung
* the parameter: der Parameter
* the parameters (plural): die Parameter
* the function parameter: der Funktionsparameter
* the default parameter: der Defaultparameter
* the body parameter: der Body-Parameter
* the request body parameter: der Requestbody-Parameter
* the path parameter: der Pfad-Parameter
* the query parameter: der Query-Parameter
* the cookie parameter: der Cookie-Parameter
* the header parameter: der Header-Parameter
* the form parameter: der Formular-Parameter
* the payload: die Payload
* the performance: NOT die Performance
* the query: die Query
* the recap: die Zusammenfassung
* the request (what the client sends to the server): der Request
* the request body: der Requestbody
* the request bodies (plural): die Requestbodys
* the response (what the server sends back to the client): die Response
* the return type: der Rückgabetyp
* the return value: der Rückgabewert
* the startup (the event of the app): der Startup
* the shutdown (the event of the app): der Shutdown
* the startup event: das Startup-Event
* the shutdown event: das Shutdown-Event
* the startup (of the server): das Hochfahren
* the startup (the company): das Startup
* the SDK: das SDK
* the tag: der Tag
* the type annotation: die Typannotation
* the type hint: der Typhinweis
* the wildcard: die Wildcard
* the worker class: die Workerklasse
* the worker class: NOT die Arbeiterklasse
* the worker process: der Workerprozess
* the worker process: NOT der Arbeiterprozess
* to commit: committen
* to deploy (in the cloud): deployen
* to modify: ändern
* to serve (an application): bereitstellen
* to serve (a response): ausliefern
* to serve: NOT bedienen
* to upgrade: aktualisieren
* to wrap: wrappen
* to wrap: NOT hüllen
* `foo` as a `type`: `foo` vom Typ `type`
* `foo` as a `type`: `foo`, ein `type`
* FastAPI's X: FastAPIs X
* Starlette's Y: Starlettes Y
* X is case-sensitive: Groß-/Klein­schrei­bung ist relevant in X
* X is case-insensitive: Groß-/Klein­schrei­bung ist nicht relevant in X
* standard Python: Standard-Python
* deprecated: deprecatet
### Other rules
Preserve indentation. Keep emoticons. Encode in utf-8. Use Linux line breaks (LF).
Preserve indentation. Keep emojis. Encode in utf-8. Use Linux line breaks (LF).

View File

@@ -1,23 +1,28 @@
tiangolo:
login: tiangolo
count: 808
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: 52
avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=85ceac49fb87138aebe8d663912e359447329090&v=4
count: 53
avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=0facffe3abf87f57a1f05fa773d1119cc5c2f6a5&v=4
url: https://github.com/alejsdev
pre-commit-ci:
login: pre-commit-ci
count: 50
avatarUrl: https://avatars.githubusercontent.com/in/68672?v=4
url: https://github.com/apps/pre-commit-ci
YuriiMotov:
login: YuriiMotov
count: 38
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=bc48be95c429989224786106b027f3c5e40cc354&v=4
url: https://github.com/YuriiMotov
github-actions:
login: github-actions
count: 26
@@ -28,26 +33,21 @@ Kludex:
count: 25
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=df8a3f06ba8f55ae1967a3e2d5ed882903a4e330&v=4
url: https://github.com/Kludex
YuriiMotov:
login: YuriiMotov
count: 20
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=b9b13d598dddfab529a52d264df80a900bfe7060&v=4
url: https://github.com/YuriiMotov
dmontagu:
login: dmontagu
count: 17
avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=540f30c937a6450812628b9592a1dfe91bbe148e&v=4
url: https://github.com/dmontagu
svlandeg:
login: svlandeg
count: 17
avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4
url: https://github.com/svlandeg
nilslindemann:
login: nilslindemann
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/6892179?u=1dca6a22195d6cd1ab20737c0e19a4c55d639472&v=4
url: https://github.com/nilslindemann
svlandeg:
login: svlandeg
count: 14
avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4
url: https://github.com/svlandeg
euri10:
login: euri10
count: 13
@@ -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
@@ -553,6 +553,11 @@ DanielKusyDev:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/36250676?u=2ea6114ff751fc48b55f231987a0e2582c6b1bd2&v=4
url: https://github.com/DanielKusyDev
Viicos:
login: Viicos
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/65306057?u=fcd677dc1b9bef12aa103613e5ccb3f8ce305af9&v=4
url: https://github.com/Viicos
DanielYang59:
login: DanielYang59
count: 2

View File

@@ -2,57 +2,51 @@ sponsors:
- - login: renderinc
avatarUrl: https://avatars.githubusercontent.com/u/36424661?v=4
url: https://github.com/renderinc
- login: andrew-propelauth
avatarUrl: https://avatars.githubusercontent.com/u/89474256?u=c98993dec8553c09d424ede67bbe86e5c35f48c9&v=4
url: https://github.com/andrew-propelauth
- login: blockbee-io
avatarUrl: https://avatars.githubusercontent.com/u/115143449?u=1b8620c2d6567c4df2111a371b85a51f448f9b85&v=4
url: https://github.com/blockbee-io
- login: zuplo
avatarUrl: https://avatars.githubusercontent.com/u/85497839?v=4
url: https://github.com/zuplo
- login: coderabbitai
avatarUrl: https://avatars.githubusercontent.com/u/132028505?v=4
url: https://github.com/coderabbitai
- login: greptileai
avatarUrl: https://avatars.githubusercontent.com/u/140149887?v=4
url: https://github.com/greptileai
- login: subtotal
avatarUrl: https://avatars.githubusercontent.com/u/176449348?v=4
url: https://github.com/subtotal
- login: greptileai
avatarUrl: https://avatars.githubusercontent.com/u/140149887?v=4
url: https://github.com/greptileai
- login: coderabbitai
avatarUrl: https://avatars.githubusercontent.com/u/132028505?v=4
url: https://github.com/coderabbitai
- login: zuplo
avatarUrl: https://avatars.githubusercontent.com/u/85497839?v=4
url: https://github.com/zuplo
- login: blockbee-io
avatarUrl: https://avatars.githubusercontent.com/u/115143449?u=1b8620c2d6567c4df2111a371b85a51f448f9b85&v=4
url: https://github.com/blockbee-io
- login: andrew-propelauth
avatarUrl: https://avatars.githubusercontent.com/u/89474256?u=c98993dec8553c09d424ede67bbe86e5c35f48c9&v=4
url: https://github.com/andrew-propelauth
- login: railwayapp
avatarUrl: https://avatars.githubusercontent.com/u/66716858?v=4
url: https://github.com/railwayapp
- - login: dribia
avatarUrl: https://avatars.githubusercontent.com/u/41189616?v=4
url: https://github.com/dribia
- login: svix
avatarUrl: https://avatars.githubusercontent.com/u/80175132?v=4
url: https://github.com/svix
- - login: speakeasy-api
avatarUrl: https://avatars.githubusercontent.com/u/91446104?v=4
url: https://github.com/speakeasy-api
- login: stainless-api
avatarUrl: https://avatars.githubusercontent.com/u/88061651?v=4
url: https://github.com/stainless-api
- login: speakeasy-api
avatarUrl: https://avatars.githubusercontent.com/u/91446104?v=4
url: https://github.com/speakeasy-api
- login: databento
avatarUrl: https://avatars.githubusercontent.com/u/64141749?v=4
url: https://github.com/databento
- login: svix
avatarUrl: https://avatars.githubusercontent.com/u/80175132?v=4
url: https://github.com/svix
- login: permitio
avatarUrl: https://avatars.githubusercontent.com/u/71775833?v=4
url: https://github.com/permitio
- - login: Ponte-Energy-Partners
avatarUrl: https://avatars.githubusercontent.com/u/114745848?v=4
url: https://github.com/Ponte-Energy-Partners
- login: LambdaTest-Inc
- login: databento
avatarUrl: https://avatars.githubusercontent.com/u/64141749?v=4
url: https://github.com/databento
- - login: LambdaTest-Inc
avatarUrl: https://avatars.githubusercontent.com/u/171592363?u=96606606a45fa170427206199014f2a5a2a4920b&v=4
url: https://github.com/LambdaTest-Inc
- login: Ponte-Energy-Partners
avatarUrl: https://avatars.githubusercontent.com/u/114745848?v=4
url: https://github.com/Ponte-Energy-Partners
- login: BoostryJP
avatarUrl: https://avatars.githubusercontent.com/u/57932412?v=4
url: https://github.com/BoostryJP
- login: requestly
avatarUrl: https://avatars.githubusercontent.com/u/12287519?v=4
url: https://github.com/requestly
- login: acsone
avatarUrl: https://avatars.githubusercontent.com/u/7601056?v=4
url: https://github.com/acsone
@@ -68,9 +62,6 @@ sponsors:
- login: Doist
avatarUrl: https://avatars.githubusercontent.com/u/2565372?v=4
url: https://github.com/Doist
- login: bholagabbar
avatarUrl: https://avatars.githubusercontent.com/u/11693595?v=4
url: https://github.com/bholagabbar
- - login: mainframeindustries
avatarUrl: https://avatars.githubusercontent.com/u/55092103?v=4
url: https://github.com/mainframeindustries
@@ -86,6 +77,9 @@ sponsors:
- login: ChargeStorm
avatarUrl: https://avatars.githubusercontent.com/u/26000165?v=4
url: https://github.com/ChargeStorm
- login: ibrahimpelumi6142
avatarUrl: https://avatars.githubusercontent.com/u/113442282?v=4
url: https://github.com/ibrahimpelumi6142
- login: nilslindemann
avatarUrl: https://avatars.githubusercontent.com/u/6892179?u=1dca6a22195d6cd1ab20737c0e19a4c55d639472&v=4
url: https://github.com/nilslindemann
@@ -116,124 +110,127 @@ sponsors:
- login: Leay15
avatarUrl: https://avatars.githubusercontent.com/u/32212558?u=c4aa9c1737e515959382a5515381757b1fd86c53&v=4
url: https://github.com/Leay15
- login: Karine-Bauch
avatarUrl: https://avatars.githubusercontent.com/u/90465103?u=7feb1018abb1a5631cfd9a91fea723d1ceb5f49b&v=4
url: https://github.com/Karine-Bauch
- login: jugeeem
avatarUrl: https://avatars.githubusercontent.com/u/116043716?u=ae590d79c38ac79c91b9c5caa6887d061e865a3d&v=4
url: https://github.com/jugeeem
- login: patsatsia
avatarUrl: https://avatars.githubusercontent.com/u/61111267?u=3271b85f7a37b479c8d0ae0a235182e83c166edf&v=4
url: https://github.com/patsatsia
- login: anthonycepeda
avatarUrl: https://avatars.githubusercontent.com/u/72019805?u=60bdf46240cff8fca482ff0fc07d963fd5e1a27c&v=4
url: https://github.com/anthonycepeda
- login: patricioperezv
avatarUrl: https://avatars.githubusercontent.com/u/73832292?u=5f471f156e19ee7920e62ae0f4a47b95580e61cf&v=4
url: https://github.com/patricioperezv
- login: chickenandstats
avatarUrl: https://avatars.githubusercontent.com/u/79477966?u=ae2b894aa954070db1d7830dab99b49eba4e4567&v=4
url: https://github.com/chickenandstats
- login: Karine-Bauch
avatarUrl: https://avatars.githubusercontent.com/u/90465103?u=7feb1018abb1a5631cfd9a91fea723d1ceb5f49b&v=4
url: https://github.com/Karine-Bauch
- login: kaoru0310
avatarUrl: https://avatars.githubusercontent.com/u/80977929?u=1b61d10142b490e56af932ddf08a390fae8ee94f&v=4
url: https://github.com/kaoru0310
- login: jstanden
avatarUrl: https://avatars.githubusercontent.com/u/63288?u=c3658d57d2862c607a0e19c2101c3c51876e36ad&v=4
url: https://github.com/jstanden
- login: knallgelb
avatarUrl: https://avatars.githubusercontent.com/u/2358812?u=c48cb6362b309d74cbf144bd6ad3aed3eb443e82&v=4
url: https://github.com/knallgelb
- login: dblackrun
avatarUrl: https://avatars.githubusercontent.com/u/3528486?v=4
url: https://github.com/dblackrun
- login: zsinx6
avatarUrl: https://avatars.githubusercontent.com/u/3532625?u=ba75a5dc744d1116ccfeaaf30d41cb2fe81fe8dd&v=4
url: https://github.com/zsinx6
- login: kennywakeland
avatarUrl: https://avatars.githubusercontent.com/u/3631417?u=7c8f743f1ae325dfadea7c62bbf1abd6a824fc55&v=4
url: https://github.com/kennywakeland
- login: aacayaco
avatarUrl: https://avatars.githubusercontent.com/u/3634801?u=eaadda178c964178fcb64886f6c732172c8f8219&v=4
url: https://github.com/aacayaco
- login: anomaly
avatarUrl: https://avatars.githubusercontent.com/u/3654837?v=4
url: https://github.com/anomaly
- login: mj0331
avatarUrl: https://avatars.githubusercontent.com/u/3890353?u=1c627ac1a024515b4871de5c3ebbfaa1a57f65d4&v=4
url: https://github.com/mj0331
- login: gorhack
avatarUrl: https://avatars.githubusercontent.com/u/4141690?u=ec119ebc4bdf00a7bc84657a71aa17834f4f27f3&v=4
url: https://github.com/gorhack
- login: Ryandaydev
avatarUrl: https://avatars.githubusercontent.com/u/4292423?u=679ff84cb7b988c5795a5fa583857f574a055763&v=4
url: https://github.com/Ryandaydev
- login: jaredtrog
avatarUrl: https://avatars.githubusercontent.com/u/4381365?v=4
url: https://github.com/jaredtrog
- login: chickenandstats
avatarUrl: https://avatars.githubusercontent.com/u/79477966?u=ae2b894aa954070db1d7830dab99b49eba4e4567&v=4
url: https://github.com/chickenandstats
- login: patricioperezv
avatarUrl: https://avatars.githubusercontent.com/u/73832292?u=5f471f156e19ee7920e62ae0f4a47b95580e61cf&v=4
url: https://github.com/patricioperezv
- login: anthonycepeda
avatarUrl: https://avatars.githubusercontent.com/u/72019805?u=60bdf46240cff8fca482ff0fc07d963fd5e1a27c&v=4
url: https://github.com/anthonycepeda
- login: AalbatrossGuy
avatarUrl: https://avatars.githubusercontent.com/u/68378354?u=0bdeea9356d24f638244131f6d8d1e2d2f3601ca&v=4
url: https://github.com/AalbatrossGuy
- login: patsatsia
avatarUrl: https://avatars.githubusercontent.com/u/61111267?u=3271b85f7a37b479c8d0ae0a235182e83c166edf&v=4
url: https://github.com/patsatsia
- login: oliverxchen
avatarUrl: https://avatars.githubusercontent.com/u/4471774?u=534191f25e32eeaadda22dfab4b0a428733d5489&v=4
url: https://github.com/oliverxchen
- login: paulcwatts
avatarUrl: https://avatars.githubusercontent.com/u/150269?u=1819e145d573b44f0ad74b87206d21cd60331d4e&v=4
url: https://github.com/paulcwatts
- login: robintw
avatarUrl: https://avatars.githubusercontent.com/u/296686?v=4
url: https://github.com/robintw
- login: pamelafox
avatarUrl: https://avatars.githubusercontent.com/u/297042?v=4
url: https://github.com/pamelafox
- login: wshayes
avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
url: https://github.com/wshayes
- login: koxudaxi
avatarUrl: https://avatars.githubusercontent.com/u/630670?u=507d8577b4b3670546b449c4c2ccbc5af40d72f7&v=4
url: https://github.com/koxudaxi
- login: falkben
avatarUrl: https://avatars.githubusercontent.com/u/653031?u=ad9838e089058c9e5a0bab94c0eec7cc181e0cd0&v=4
url: https://github.com/falkben
- login: mintuhouse
avatarUrl: https://avatars.githubusercontent.com/u/769950?u=ecfbd79a97d33177e0d093ddb088283cf7fe8444&v=4
url: https://github.com/mintuhouse
- login: jaredtrog
avatarUrl: https://avatars.githubusercontent.com/u/4381365?v=4
url: https://github.com/jaredtrog
- login: Ryandaydev
avatarUrl: https://avatars.githubusercontent.com/u/4292423?u=679ff84cb7b988c5795a5fa583857f574a055763&v=4
url: https://github.com/Ryandaydev
- login: gorhack
avatarUrl: https://avatars.githubusercontent.com/u/4141690?u=ec119ebc4bdf00a7bc84657a71aa17834f4f27f3&v=4
url: https://github.com/gorhack
- login: mj0331
avatarUrl: https://avatars.githubusercontent.com/u/3890353?u=1c627ac1a024515b4871de5c3ebbfaa1a57f65d4&v=4
url: https://github.com/mj0331
- login: anomaly
avatarUrl: https://avatars.githubusercontent.com/u/3654837?v=4
url: https://github.com/anomaly
- login: aacayaco
avatarUrl: https://avatars.githubusercontent.com/u/3634801?u=eaadda178c964178fcb64886f6c732172c8f8219&v=4
url: https://github.com/aacayaco
- login: kennywakeland
avatarUrl: https://avatars.githubusercontent.com/u/3631417?u=7c8f743f1ae325dfadea7c62bbf1abd6a824fc55&v=4
url: https://github.com/kennywakeland
- login: zsinx6
avatarUrl: https://avatars.githubusercontent.com/u/3532625?u=ba75a5dc744d1116ccfeaaf30d41cb2fe81fe8dd&v=4
url: https://github.com/zsinx6
- login: dblackrun
avatarUrl: https://avatars.githubusercontent.com/u/3528486?v=4
url: https://github.com/dblackrun
- login: knallgelb
avatarUrl: https://avatars.githubusercontent.com/u/2358812?u=c48cb6362b309d74cbf144bd6ad3aed3eb443e82&v=4
url: https://github.com/knallgelb
- login: dodo5522
avatarUrl: https://avatars.githubusercontent.com/u/1362607?u=9bf1e0e520cccc547c046610c468ce6115bbcf9f&v=4
url: https://github.com/dodo5522
- login: wdwinslow
avatarUrl: https://avatars.githubusercontent.com/u/11562137?u=371272f2c69e680e0559a7b0a57385e83a5dc728&v=4
url: https://github.com/wdwinslow
- login: jsoques
avatarUrl: https://avatars.githubusercontent.com/u/12414216?u=620921d94196546cc8b9eae2cc4cbc3f95bab42f&v=4
url: https://github.com/jsoques
- login: dannywade
avatarUrl: https://avatars.githubusercontent.com/u/13680237?u=418ee985bd41577b20fde81417fb2d901e875e8a&v=4
url: https://github.com/dannywade
- login: khadrawy
avatarUrl: https://avatars.githubusercontent.com/u/13686061?u=59f25ef42ecf04c22657aac4238ce0e2d3d30304&v=4
url: https://github.com/khadrawy
- login: mjohnsey
avatarUrl: https://avatars.githubusercontent.com/u/16784016?u=38fad2e6b411244560b3af99c5f5a4751bc81865&v=4
url: https://github.com/mjohnsey
- login: ashi-agrawal
avatarUrl: https://avatars.githubusercontent.com/u/17105294?u=99c7a854035e5398d8e7b674f2d42baae6c957f8&v=4
url: https://github.com/ashi-agrawal
- login: mintuhouse
avatarUrl: https://avatars.githubusercontent.com/u/769950?u=ecfbd79a97d33177e0d093ddb088283cf7fe8444&v=4
url: https://github.com/mintuhouse
- login: falkben
avatarUrl: https://avatars.githubusercontent.com/u/653031?u=ad9838e089058c9e5a0bab94c0eec7cc181e0cd0&v=4
url: https://github.com/falkben
- login: koxudaxi
avatarUrl: https://avatars.githubusercontent.com/u/630670?u=507d8577b4b3670546b449c4c2ccbc5af40d72f7&v=4
url: https://github.com/koxudaxi
- login: wshayes
avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
url: https://github.com/wshayes
- login: pamelafox
avatarUrl: https://avatars.githubusercontent.com/u/297042?v=4
url: https://github.com/pamelafox
- login: robintw
avatarUrl: https://avatars.githubusercontent.com/u/296686?v=4
url: https://github.com/robintw
- login: jstanden
avatarUrl: https://avatars.githubusercontent.com/u/63288?u=c3658d57d2862c607a0e19c2101c3c51876e36ad&v=4
url: https://github.com/jstanden
- login: RaamEEIL
avatarUrl: https://avatars.githubusercontent.com/u/20320552?v=4
url: https://github.com/RaamEEIL
- login: ternaus
avatarUrl: https://avatars.githubusercontent.com/u/5481618?u=513a26b02a39e7a28d587cd37c6cc877ea368e6e&v=4
url: https://github.com/ternaus
- login: eseglem
avatarUrl: https://avatars.githubusercontent.com/u/5920492?u=208d419cf667b8ac594c82a8db01932c7e50d057&v=4
url: https://github.com/eseglem
- login: FernandoCelmer
avatarUrl: https://avatars.githubusercontent.com/u/6262214?u=58ba6d5888fa7f355934e52db19f950e20b38162&v=4
url: https://github.com/FernandoCelmer
- login: Rehket
avatarUrl: https://avatars.githubusercontent.com/u/7015688?u=3afb0ba200feebbc7f958950e92db34df2a3c172&v=4
url: https://github.com/Rehket
- login: ashi-agrawal
avatarUrl: https://avatars.githubusercontent.com/u/17105294?u=99c7a854035e5398d8e7b674f2d42baae6c957f8&v=4
url: https://github.com/ashi-agrawal
- login: mjohnsey
avatarUrl: https://avatars.githubusercontent.com/u/16784016?u=38fad2e6b411244560b3af99c5f5a4751bc81865&v=4
url: https://github.com/mjohnsey
- login: khadrawy
avatarUrl: https://avatars.githubusercontent.com/u/13686061?u=59f25ef42ecf04c22657aac4238ce0e2d3d30304&v=4
url: https://github.com/khadrawy
- login: dannywade
avatarUrl: https://avatars.githubusercontent.com/u/13680237?u=418ee985bd41577b20fde81417fb2d901e875e8a&v=4
url: https://github.com/dannywade
- login: jsoques
avatarUrl: https://avatars.githubusercontent.com/u/12414216?u=620921d94196546cc8b9eae2cc4cbc3f95bab42f&v=4
url: https://github.com/jsoques
- login: wdwinslow
avatarUrl: https://avatars.githubusercontent.com/u/11562137?u=371272f2c69e680e0559a7b0a57385e83a5dc728&v=4
url: https://github.com/wdwinslow
- login: hiancdtrsnm
avatarUrl: https://avatars.githubusercontent.com/u/7343177?v=4
url: https://github.com/hiancdtrsnm
- - login: manoelpqueiroz
- login: Rehket
avatarUrl: https://avatars.githubusercontent.com/u/7015688?u=3afb0ba200feebbc7f958950e92db34df2a3c172&v=4
url: https://github.com/Rehket
- login: FernandoCelmer
avatarUrl: https://avatars.githubusercontent.com/u/6262214?u=58ba6d5888fa7f355934e52db19f950e20b38162&v=4
url: https://github.com/FernandoCelmer
- login: eseglem
avatarUrl: https://avatars.githubusercontent.com/u/5920492?u=208d419cf667b8ac594c82a8db01932c7e50d057&v=4
url: https://github.com/eseglem
- login: ternaus
avatarUrl: https://avatars.githubusercontent.com/u/5481618?u=513a26b02a39e7a28d587cd37c6cc877ea368e6e&v=4
url: https://github.com/ternaus
- - login: Artur-Galstyan
avatarUrl: https://avatars.githubusercontent.com/u/63471891?u=e8691f386037e51a737cc0ba866cd8c89e5cf109&v=4
url: https://github.com/Artur-Galstyan
- login: manoelpqueiroz
avatarUrl: https://avatars.githubusercontent.com/u/23669137?u=b12e84b28a84369ab5b30bd5a79e5788df5a0756&v=4
url: https://github.com/manoelpqueiroz
- - login: pawamoy
@@ -254,9 +251,12 @@ sponsors:
- login: hgalytoby
avatarUrl: https://avatars.githubusercontent.com/u/50397689?u=6cc9028f3db63f8f60ad21c17b1ce4b88c4e2e60&v=4
url: https://github.com/hgalytoby
- login: nisutec
avatarUrl: https://avatars.githubusercontent.com/u/25281462?u=e562484c451fdfc59053163f64405f8eb262b8b0&v=4
url: https://github.com/nisutec
- login: johnl28
avatarUrl: https://avatars.githubusercontent.com/u/54412955?u=47dd06082d1c39caa90c752eb55566e4f3813957&v=4
url: https://github.com/johnl28
- login: danielunderwood
avatarUrl: https://avatars.githubusercontent.com/u/4472301?v=4
url: https://github.com/danielunderwood
- login: hoenie-ams
avatarUrl: https://avatars.githubusercontent.com/u/25708487?u=cda07434f0509ac728d9edf5e681117c0f6b818b&v=4
url: https://github.com/hoenie-ams
@@ -267,93 +267,87 @@ sponsors:
avatarUrl: https://avatars.githubusercontent.com/u/33275230?u=eb223cad27017bb1e936ee9b429b450d092d0236&v=4
url: https://github.com/engineerjoe440
- login: bnkc
avatarUrl: https://avatars.githubusercontent.com/u/34930566?u=db5e6f4f87836cad26c2aa90ce390ce49041c5a9&v=4
avatarUrl: https://avatars.githubusercontent.com/u/34930566?u=4771ac4e64066f0847d40e5b29910adabd9b2372&v=4
url: https://github.com/bnkc
- login: petercool
avatarUrl: https://avatars.githubusercontent.com/u/37613029?u=75aa8c6729e6e8f85a300561c4dbeef9d65c8797&v=4
url: https://github.com/petercool
- login: johnl28
avatarUrl: https://avatars.githubusercontent.com/u/54412955?u=47dd06082d1c39caa90c752eb55566e4f3813957&v=4
url: https://github.com/johnl28
- login: PunRabbit
avatarUrl: https://avatars.githubusercontent.com/u/70463212?u=1a835cfbc99295a60c8282f6aa6199d1b42241a5&v=4
url: https://github.com/PunRabbit
- login: PelicanQ
avatarUrl: https://avatars.githubusercontent.com/u/77930606?v=4
url: https://github.com/PelicanQ
- login: WillHogan
avatarUrl: https://avatars.githubusercontent.com/u/1661551?u=8a80356e3e7d5a417157aba7ea565dabc8678327&v=4
url: https://github.com/WillHogan
- login: PunRabbit
avatarUrl: https://avatars.githubusercontent.com/u/70463212?u=1a835cfbc99295a60c8282f6aa6199d1b42241a5&v=4
url: https://github.com/PunRabbit
- login: my3
avatarUrl: https://avatars.githubusercontent.com/u/1825270?v=4
url: https://github.com/my3
- login: danielunderwood
avatarUrl: https://avatars.githubusercontent.com/u/4472301?v=4
url: https://github.com/danielunderwood
- login: ddanier
avatarUrl: https://avatars.githubusercontent.com/u/113563?u=ed1dc79de72f93bd78581f88ebc6952b62f472da&v=4
url: https://github.com/ddanier
- login: bryanculbertson
avatarUrl: https://avatars.githubusercontent.com/u/144028?u=defda4f90e93429221cc667500944abde60ebe4a&v=4
url: https://github.com/bryanculbertson
- login: slafs
avatarUrl: https://avatars.githubusercontent.com/u/210173?v=4
url: https://github.com/slafs
- login: ceb10n
avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
url: https://github.com/ceb10n
- login: tochikuji
avatarUrl: https://avatars.githubusercontent.com/u/851759?v=4
url: https://github.com/tochikuji
- login: WillHogan
avatarUrl: https://avatars.githubusercontent.com/u/1661551?u=8a80356e3e7d5a417157aba7ea565dabc8678327&v=4
url: https://github.com/WillHogan
- login: miguelgr
avatarUrl: https://avatars.githubusercontent.com/u/1484589?u=54556072b8136efa12ae3b6902032ea2a39ace4b&v=4
url: https://github.com/miguelgr
- login: xncbf
avatarUrl: https://avatars.githubusercontent.com/u/9462045?u=a80a7bb349555b277645632ed66639ff43400614&v=4
url: https://github.com/xncbf
- login: DMantis
avatarUrl: https://avatars.githubusercontent.com/u/9536869?u=652dd0d49717803c0cbcbf44f7740e53cf2d4892&v=4
url: https://github.com/DMantis
- login: hard-coders
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
url: https://github.com/hard-coders
- login: mntolia
avatarUrl: https://avatars.githubusercontent.com/u/10390224?v=4
url: https://github.com/mntolia
- login: Zuzah
avatarUrl: https://avatars.githubusercontent.com/u/10934846?u=1ef43e075ddc87bd1178372bf4d95ee6175cae27&v=4
url: https://github.com/Zuzah
- login: TheR1D
avatarUrl: https://avatars.githubusercontent.com/u/16740832?u=b0dfdbdb27b79729430c71c6128962f77b7b53f7&v=4
url: https://github.com/TheR1D
- login: tochikuji
avatarUrl: https://avatars.githubusercontent.com/u/851759?v=4
url: https://github.com/tochikuji
- login: ceb10n
avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
url: https://github.com/ceb10n
- login: slafs
avatarUrl: https://avatars.githubusercontent.com/u/210173?v=4
url: https://github.com/slafs
- login: bryanculbertson
avatarUrl: https://avatars.githubusercontent.com/u/144028?u=defda4f90e93429221cc667500944abde60ebe4a&v=4
url: https://github.com/bryanculbertson
- login: ddanier
avatarUrl: https://avatars.githubusercontent.com/u/113563?u=ed1dc79de72f93bd78581f88ebc6952b62f472da&v=4
url: https://github.com/ddanier
- login: nisutec
avatarUrl: https://avatars.githubusercontent.com/u/25281462?u=e562484c451fdfc59053163f64405f8eb262b8b0&v=4
url: https://github.com/nisutec
- login: joshuatz
avatarUrl: https://avatars.githubusercontent.com/u/17817563?u=f1bf05b690d1fc164218f0b420cdd3acb7913e21&v=4
url: https://github.com/joshuatz
- login: rangulvers
avatarUrl: https://avatars.githubusercontent.com/u/5235430?u=e254d4af4ace5a05fa58372ae677c7d26f0d5a53&v=4
url: https://github.com/rangulvers
- login: sdevkota
avatarUrl: https://avatars.githubusercontent.com/u/5250987?u=4ed9a120c89805a8aefda1cbdc0cf6512e64d1b4&v=4
url: https://github.com/sdevkota
- login: Baghdady92
avatarUrl: https://avatars.githubusercontent.com/u/5708590?v=4
url: https://github.com/Baghdady92
- login: KentShikama
avatarUrl: https://avatars.githubusercontent.com/u/6329898?u=8b236810db9b96333230430837e1f021f9246da1&v=4
url: https://github.com/KentShikama
- login: katnoria
avatarUrl: https://avatars.githubusercontent.com/u/7674948?u=09767eb13e07e09496c5fee4e5ce21d9eac34a56&v=4
url: https://github.com/katnoria
- login: harsh183
avatarUrl: https://avatars.githubusercontent.com/u/7780198?v=4
url: https://github.com/harsh183
- login: TheR1D
avatarUrl: https://avatars.githubusercontent.com/u/16740832?u=b0dfdbdb27b79729430c71c6128962f77b7b53f7&v=4
url: https://github.com/TheR1D
- login: Zuzah
avatarUrl: https://avatars.githubusercontent.com/u/10934846?u=1ef43e075ddc87bd1178372bf4d95ee6175cae27&v=4
url: https://github.com/Zuzah
- login: mntolia
avatarUrl: https://avatars.githubusercontent.com/u/10390224?v=4
url: https://github.com/mntolia
- login: hard-coders
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=78d12d1acdf853c817700145e73de7fd9e5d068b&v=4
url: https://github.com/hard-coders
- login: DMantis
avatarUrl: https://avatars.githubusercontent.com/u/9536869?u=652dd0d49717803c0cbcbf44f7740e53cf2d4892&v=4
url: https://github.com/DMantis
- login: xncbf
avatarUrl: https://avatars.githubusercontent.com/u/9462045?u=a80a7bb349555b277645632ed66639ff43400614&v=4
url: https://github.com/xncbf
- login: moonape1226
avatarUrl: https://avatars.githubusercontent.com/u/8532038?u=d9f8b855a429fff9397c3833c2ff83849ebf989d&v=4
url: https://github.com/moonape1226
- - login: andrecorumba
avatarUrl: https://avatars.githubusercontent.com/u/37807517?u=9b9be3b41da9bda60957da9ef37b50dbf65baa61&v=4
url: https://github.com/andrecorumba
- login: KOZ39
- login: harsh183
avatarUrl: https://avatars.githubusercontent.com/u/7780198?v=4
url: https://github.com/harsh183
- login: katnoria
avatarUrl: https://avatars.githubusercontent.com/u/7674948?u=09767eb13e07e09496c5fee4e5ce21d9eac34a56&v=4
url: https://github.com/katnoria
- login: KentShikama
avatarUrl: https://avatars.githubusercontent.com/u/6329898?u=8b236810db9b96333230430837e1f021f9246da1&v=4
url: https://github.com/KentShikama
- login: Baghdady92
avatarUrl: https://avatars.githubusercontent.com/u/5708590?v=4
url: https://github.com/Baghdady92
- login: sdevkota
avatarUrl: https://avatars.githubusercontent.com/u/5250987?u=4ed9a120c89805a8aefda1cbdc0cf6512e64d1b4&v=4
url: https://github.com/sdevkota
- login: rangulvers
avatarUrl: https://avatars.githubusercontent.com/u/5235430?u=e254d4af4ace5a05fa58372ae677c7d26f0d5a53&v=4
url: https://github.com/rangulvers
- - login: KOZ39
avatarUrl: https://avatars.githubusercontent.com/u/38822500?u=9dfc0a697df1c9628f08e20dc3fb17b1afc4e5a7&v=4
url: https://github.com/KOZ39
- login: rwxd
@@ -365,27 +359,24 @@ sponsors:
- login: Olegt0rr
avatarUrl: https://avatars.githubusercontent.com/u/25399456?u=3e87b5239a2f4600975ba13be73054f8567c6060&v=4
url: https://github.com/Olegt0rr
- login: dinoz0rg
avatarUrl: https://avatars.githubusercontent.com/u/32940067?u=739cda1eb123a2dd5e1db45c361396f239e23f8b&v=4
url: https://github.com/dinoz0rg
- login: larsyngvelundin
avatarUrl: https://avatars.githubusercontent.com/u/34173819?u=74958599695bf83ac9f1addd935a51548a10c6b0&v=4
url: https://github.com/larsyngvelundin
- login: hippoley
avatarUrl: https://avatars.githubusercontent.com/u/135493401?u=1164ef48a645a7c12664fabc1638fbb7e1c459b0&v=4
url: https://github.com/hippoley
- login: 4anklee
avatarUrl: https://avatars.githubusercontent.com/u/144109238?u=a79c0d581b2a3d8f3897e7ef4c012640a6c1eb3a&v=4
url: https://github.com/4anklee
- login: andrecorumba
avatarUrl: https://avatars.githubusercontent.com/u/37807517?u=9b9be3b41da9bda60957da9ef37b50dbf65baa61&v=4
url: https://github.com/andrecorumba
- login: CoderDeltaLAN
avatarUrl: https://avatars.githubusercontent.com/u/152043745?u=4ff541efffb7d134e60c5fcf2dd1e343f90bb782&v=4
url: https://github.com/CoderDeltaLAN
- login: onestn
avatarUrl: https://avatars.githubusercontent.com/u/62360849?u=746dd21c34e7e06eefb11b03e8bb01aaae3c2a4f&v=4
url: https://github.com/onestn
- login: hippoley
avatarUrl: https://avatars.githubusercontent.com/u/135493401?u=1164ef48a645a7c12664fabc1638fbb7e1c459b0&v=4
url: https://github.com/hippoley
- login: nayasinghania
avatarUrl: https://avatars.githubusercontent.com/u/74111380?u=752e99a5e139389fdc0a0677122adc08438eb076&v=4
url: https://github.com/nayasinghania
- login: onestn
avatarUrl: https://avatars.githubusercontent.com/u/62360849?u=746dd21c34e7e06eefb11b03e8bb01aaae3c2a4f&v=4
url: https://github.com/onestn
- login: Toothwitch
avatarUrl: https://avatars.githubusercontent.com/u/1710406?u=5eebb23b46cd26e48643b9e5179536cad491c17a&v=4
url: https://github.com/Toothwitch

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,495 +1,495 @@
- name: full-stack-fastapi-template
html_url: https://github.com/fastapi/full-stack-fastapi-template
stars: 39475
stars: 41312
owner_login: fastapi
owner_html_url: https://github.com/fastapi
- name: Hello-Python
html_url: https://github.com/mouredev/Hello-Python
stars: 33090
stars: 34206
owner_login: mouredev
owner_html_url: https://github.com/mouredev
- name: serve
html_url: https://github.com/jina-ai/serve
stars: 21798
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: 20258
stars: 20661
owner_login: Zeyi-Lin
owner_html_url: https://github.com/Zeyi-Lin
- name: sqlmodel
html_url: https://github.com/fastapi/sqlmodel
stars: 17212
stars: 17567
owner_login: fastapi
owner_html_url: https://github.com/fastapi
- name: Douyin_TikTok_Download_API
html_url: https://github.com/Evil0ctal/Douyin_TikTok_Download_API
stars: 15145
owner_login: Evil0ctal
owner_html_url: https://github.com/Evil0ctal
- name: fastapi-best-practices
html_url: https://github.com/zhanymkanov/fastapi-best-practices
stars: 14644
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: 16132
owner_login: Evil0ctal
owner_html_url: https://github.com/Evil0ctal
- name: SurfSense
html_url: https://github.com/MODSetter/SurfSense
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: 12320
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: 11174
stars: 11478
owner_login: tadata-org
owner_html_url: https://github.com/tadata-org
- name: SurfSense
html_url: https://github.com/MODSetter/SurfSense
stars: 10858
owner_login: MODSetter
owner_html_url: https://github.com/MODSetter
- name: awesome-fastapi
html_url: https://github.com/mjhea0/awesome-fastapi
stars: 10758
stars: 11018
owner_login: mjhea0
owner_html_url: https://github.com/mjhea0
- name: XHS-Downloader
html_url: https://github.com/JoeanAmier/XHS-Downloader
stars: 9313
stars: 9938
owner_login: JoeanAmier
owner_html_url: https://github.com/JoeanAmier
- name: FastUI
html_url: https://github.com/pydantic/FastUI
stars: 8915
owner_login: pydantic
owner_html_url: https://github.com/pydantic
- name: polar
html_url: https://github.com/polarsource/polar
stars: 8339
stars: 9348
owner_login: polarsource
owner_html_url: https://github.com/polarsource
- name: FastUI
html_url: https://github.com/pydantic/FastUI
stars: 8949
owner_login: pydantic
owner_html_url: https://github.com/pydantic
- name: FileCodeBox
html_url: https://github.com/vastsa/FileCodeBox
stars: 7721
stars: 8060
owner_login: vastsa
owner_html_url: https://github.com/vastsa
- name: nonebot2
html_url: https://github.com/nonebot/nonebot2
stars: 7170
stars: 7311
owner_login: nonebot
owner_html_url: https://github.com/nonebot
- name: hatchet
html_url: https://github.com/hatchet-dev/hatchet
stars: 6253
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: 5849
stars: 5970
owner_login: fastapi-users
owner_html_url: https://github.com/fastapi-users
- name: serge
html_url: https://github.com/serge-chat/serge
stars: 5756
stars: 5751
owner_login: serge-chat
owner_html_url: https://github.com/serge-chat
- name: strawberry
html_url: https://github.com/strawberry-graphql/strawberry
stars: 4569
stars: 4598
owner_login: strawberry-graphql
owner_html_url: https://github.com/strawberry-graphql
- name: chatgpt-web-share
html_url: https://github.com/chatpire/chatgpt-web-share
stars: 4294
owner_login: chatpire
owner_html_url: https://github.com/chatpire
- name: poem
html_url: https://github.com/poem-web/poem
stars: 4276
owner_login: poem-web
owner_html_url: https://github.com/poem-web
- name: dynaconf
html_url: https://github.com/dynaconf/dynaconf
stars: 4202
owner_login: dynaconf
owner_html_url: https://github.com/dynaconf
- name: atrilabs-engine
html_url: https://github.com/Atri-Labs/atrilabs-engine
stars: 4093
owner_login: Atri-Labs
owner_html_url: https://github.com/Atri-Labs
- 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: 4019
stars: 4359
owner_login: remsky
owner_html_url: https://github.com/remsky
- name: poem
html_url: https://github.com/poem-web/poem
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: 4279
owner_login: chatpire
owner_html_url: https://github.com/chatpire
- name: dynaconf
html_url: https://github.com/dynaconf/dynaconf
stars: 4244
owner_login: dynaconf
owner_html_url: https://github.com/dynaconf
- 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: 4086
owner_login: Atri-Labs
owner_html_url: https://github.com/Atri-Labs
- name: logfire
html_url: https://github.com/pydantic/logfire
stars: 3805
stars: 3975
owner_login: pydantic
owner_html_url: https://github.com/pydantic
- name: LitServe
html_url: https://github.com/Lightning-AI/LitServe
stars: 3719
stars: 3797
owner_login: Lightning-AI
owner_html_url: https://github.com/Lightning-AI
- name: fastapi-admin
html_url: https://github.com/fastapi-admin/fastapi-admin
stars: 3632
owner_login: fastapi-admin
owner_html_url: https://github.com/fastapi-admin
- name: datamodel-code-generator
html_url: https://github.com/koxudaxi/datamodel-code-generator
stars: 3609
owner_login: koxudaxi
owner_html_url: https://github.com/koxudaxi
- name: huma
html_url: https://github.com/danielgtaylor/huma
stars: 3603
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: 3731
owner_login: koxudaxi
owner_html_url: https://github.com/koxudaxi
- name: fastapi-admin
html_url: https://github.com/fastapi-admin/fastapi-admin
stars: 3697
owner_login: fastapi-admin
owner_html_url: https://github.com/fastapi-admin
- name: farfalle
html_url: https://github.com/rashadphz/farfalle
stars: 3490
stars: 3506
owner_login: rashadphz
owner_html_url: https://github.com/rashadphz
- name: tracecat
html_url: https://github.com/TracecatHQ/tracecat
stars: 3379
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: 3135
stars: 3134
owner_login: ml-tooling
owner_html_url: https://github.com/ml-tooling
- name: docarray
html_url: https://github.com/docarray/docarray
stars: 3114
stars: 3111
owner_login: docarray
owner_html_url: https://github.com/docarray
- name: devpush
html_url: https://github.com/hunvreus/devpush
stars: 3097
owner_login: hunvreus
owner_html_url: https://github.com/hunvreus
- name: fastapi-realworld-example-app
html_url: https://github.com/nsidnev/fastapi-realworld-example-app
stars: 3050
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: 2911
stars: 2908
owner_login: tiangolo
owner_html_url: https://github.com/tiangolo
- name: mcp-context-forge
html_url: https://github.com/IBM/mcp-context-forge
stars: 2899
owner_login: IBM
owner_html_url: https://github.com/IBM
- name: best-of-web-python
html_url: https://github.com/ml-tooling/best-of-web-python
stars: 2648
owner_login: ml-tooling
owner_html_url: https://github.com/ml-tooling
- name: FastAPI-template
html_url: https://github.com/s3rius/FastAPI-template
stars: 2637
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: 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: 2599
stars: 2648
owner_login: sahibzada-allahyar
owner_html_url: https://github.com/sahibzada-allahyar
- name: fastapi-react
html_url: https://github.com/Buuntu/fastapi-react
stars: 2569
owner_login: Buuntu
owner_html_url: https://github.com/Buuntu
- name: Yuxi-Know
html_url: https://github.com/xerrors/Yuxi-Know
stars: 2563
owner_login: xerrors
owner_html_url: https://github.com/xerrors
- name: sqladmin
html_url: https://github.com/aminalaee/sqladmin
stars: 2558
stars: 2637
owner_login: aminalaee
owner_html_url: https://github.com/aminalaee
- name: fastapi-react
html_url: https://github.com/Buuntu/fastapi-react
stars: 2573
owner_login: Buuntu
owner_html_url: https://github.com/Buuntu
- name: RasaGPT
html_url: https://github.com/paulpierre/RasaGPT
stars: 2451
stars: 2460
owner_login: paulpierre
owner_html_url: https://github.com/paulpierre
- name: supabase-py
html_url: https://github.com/supabase/supabase-py
stars: 2344
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: 2335
stars: 2337
owner_login: dot-agent
owner_html_url: https://github.com/dot-agent
- name: fastapi-utils
html_url: https://github.com/fastapiutils/fastapi-utils
stars: 2291
stars: 2299
owner_login: fastapiutils
owner_html_url: https://github.com/fastapiutils
- name: 30-Days-of-Python
html_url: https://github.com/codingforentrepreneurs/30-Days-of-Python
stars: 2220
owner_login: codingforentrepreneurs
owner_html_url: https://github.com/codingforentrepreneurs
- name: langserve
html_url: https://github.com/langchain-ai/langserve
stars: 2215
stars: 2255
owner_login: langchain-ai
owner_html_url: https://github.com/langchain-ai
- 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: 2122
stars: 2154
owner_login: widgetti
owner_html_url: https://github.com/widgetti
- name: mangum
html_url: https://github.com/Kludex/mangum
stars: 2029
stars: 2071
owner_login: Kludex
owner_html_url: https://github.com/Kludex
- name: agentkit
html_url: https://github.com/BCG-X-Official/agentkit
stars: 1912
owner_login: BCG-X-Official
owner_html_url: https://github.com/BCG-X-Official
- name: manage-fastapi
html_url: https://github.com/ycd/manage-fastapi
stars: 1885
owner_login: ycd
owner_html_url: https://github.com/ycd
- name: openapi-python-client
html_url: https://github.com/openapi-generators/openapi-python-client
stars: 1862
owner_login: openapi-generators
owner_html_url: https://github.com/openapi-generators
- name: piccolo
html_url: https://github.com/piccolo-orm/piccolo
stars: 1836
owner_login: piccolo-orm
owner_html_url: https://github.com/piccolo-orm
- name: fastapi_best_architecture
html_url: https://github.com/fastapi-practices/fastapi_best_architecture
stars: 2036
owner_login: fastapi-practices
owner_html_url: https://github.com/fastapi-practices
- name: vue-fastapi-admin
html_url: https://github.com/mizhexiaoxiao/vue-fastapi-admin
stars: 1831
stars: 1983
owner_login: mizhexiaoxiao
owner_html_url: https://github.com/mizhexiaoxiao
- name: python-week-2022
html_url: https://github.com/rochacbruno/python-week-2022
stars: 1817
owner_login: rochacbruno
owner_html_url: https://github.com/rochacbruno
- name: slowapi
html_url: https://github.com/laurentS/slowapi
stars: 1798
owner_login: laurentS
owner_html_url: https://github.com/laurentS
- name: fastapi-cache
html_url: https://github.com/long2ice/fastapi-cache
stars: 1789
owner_login: long2ice
owner_html_url: https://github.com/long2ice
- name: ormar
html_url: https://github.com/collerek/ormar
stars: 1783
owner_login: collerek
owner_html_url: https://github.com/collerek
- name: termpair
html_url: https://github.com/cs01/termpair
stars: 1716
owner_login: cs01
owner_html_url: https://github.com/cs01
- name: FastAPI-boilerplate
html_url: https://github.com/benavlabs/FastAPI-boilerplate
stars: 1660
owner_login: benavlabs
owner_html_url: https://github.com/benavlabs
- 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: 1638
stars: 1920
owner_login: wassim249
owner_html_url: https://github.com/wassim249
- name: langchain-serve
html_url: https://github.com/jina-ai/langchain-serve
stars: 1635
owner_login: jina-ai
owner_html_url: https://github.com/jina-ai
- name: awesome-fastapi-projects
html_url: https://github.com/Kludex/awesome-fastapi-projects
stars: 1589
owner_login: Kludex
owner_html_url: https://github.com/Kludex
- name: fastapi-pagination
html_url: https://github.com/uriyyo/fastapi-pagination
stars: 1585
owner_login: uriyyo
owner_html_url: https://github.com/uriyyo
- name: coronavirus-tracker-api
html_url: https://github.com/ExpDev07/coronavirus-tracker-api
stars: 1574
owner_login: ExpDev07
owner_html_url: https://github.com/ExpDev07
- name: openapi-python-client
html_url: https://github.com/openapi-generators/openapi-python-client
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: 1891
owner_login: laurentS
owner_html_url: https://github.com/laurentS
- name: piccolo
html_url: https://github.com/piccolo-orm/piccolo
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: ormar
html_url: https://github.com/collerek/ormar
stars: 1797
owner_login: collerek
owner_html_url: https://github.com/collerek
- name: FastAPI-boilerplate
html_url: https://github.com/benavlabs/FastAPI-boilerplate
stars: 1792
owner_login: benavlabs
owner_html_url: https://github.com/benavlabs
- name: termpair
html_url: https://github.com/cs01/termpair
stars: 1727
owner_login: cs01
owner_html_url: https://github.com/cs01
- name: fastapi-crudrouter
html_url: https://github.com/awtkns/fastapi-crudrouter
stars: 1559
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: 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: 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: 1592
owner_login: Kludex
owner_html_url: https://github.com/Kludex
- name: bracket
html_url: https://github.com/evroon/bracket
stars: 1489
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: 1475
stars: 1512
owner_login: amisadmin
owner_html_url: https://github.com/amisadmin
- name: fastcrud
html_url: https://github.com/benavlabs/fastcrud
stars: 1471
owner_login: benavlabs
owner_html_url: https://github.com/benavlabs
- name: fastapi-boilerplate
html_url: https://github.com/teamhide/fastapi-boilerplate
stars: 1436
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: 1426
stars: 1435
owner_login: DjangoEx
owner_html_url: https://github.com/DjangoEx
- name: fastcrud
html_url: https://github.com/benavlabs/fastcrud
stars: 1414
owner_login: benavlabs
owner_html_url: https://github.com/benavlabs
- name: prometheus-fastapi-instrumentator
html_url: https://github.com/trallnag/prometheus-fastapi-instrumentator
stars: 1388
stars: 1417
owner_login: trallnag
owner_html_url: https://github.com/trallnag
- name: fastapi_best_architecture
html_url: https://github.com/fastapi-practices/fastapi_best_architecture
stars: 1378
owner_login: fastapi-practices
owner_html_url: https://github.com/fastapi-practices
- name: fastapi-code-generator
html_url: https://github.com/koxudaxi/fastapi-code-generator
stars: 1375
stars: 1382
owner_login: koxudaxi
owner_html_url: https://github.com/koxudaxi
- name: budgetml
html_url: https://github.com/ebhy/budgetml
stars: 1345
owner_login: ebhy
owner_html_url: https://github.com/ebhy
- name: fastapi-tutorial
html_url: https://github.com/liaogx/fastapi-tutorial
stars: 1327
owner_login: liaogx
owner_html_url: https://github.com/liaogx
- name: fastapi-alembic-sqlmodel-async
html_url: https://github.com/jonra1993/fastapi-alembic-sqlmodel-async
stars: 1259
owner_login: jonra1993
owner_html_url: https://github.com/jonra1993
- name: fastapi-scaff
html_url: https://github.com/atpuxiner/fastapi-scaff
stars: 1255
stars: 1367
owner_login: atpuxiner
owner_html_url: https://github.com/atpuxiner
- name: bedrock-chat
html_url: https://github.com/aws-samples/bedrock-chat
stars: 1254
owner_login: aws-samples
owner_html_url: https://github.com/aws-samples
- name: fastapi-tutorial
html_url: https://github.com/liaogx/fastapi-tutorial
stars: 1360
owner_login: liaogx
owner_html_url: https://github.com/liaogx
- name: budgetml
html_url: https://github.com/ebhy/budgetml
stars: 1343
owner_login: ebhy
owner_html_url: https://github.com/ebhy
- name: bolt-python
html_url: https://github.com/slackapi/bolt-python
stars: 1253
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: 1268
owner_login: aws-samples
owner_html_url: https://github.com/aws-samples
- name: fastapi-alembic-sqlmodel-async
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: 1217
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: 1176
owner_login: langchain-ai
owner_html_url: https://github.com/langchain-ai
- name: restish
html_url: https://github.com/rest-sh/restish
stars: 1140
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: 1138
stars: 1162
owner_login: art049
owner_html_url: https://github.com/art049
- name: authx
html_url: https://github.com/yezz123/authx
stars: 1119
owner_login: yezz123
owner_html_url: https://github.com/yezz123
- name: NoteDiscovery
html_url: https://github.com/gamosoft/NoteDiscovery
stars: 1107
owner_login: gamosoft
owner_html_url: https://github.com/gamosoft
- name: flock
html_url: https://github.com/Onelevenvy/flock
stars: 1055
owner_login: Onelevenvy
owner_html_url: https://github.com/Onelevenvy
- name: fastapi-observability
html_url: https://github.com/blueswen/fastapi-observability
stars: 1038
owner_login: blueswen
owner_html_url: https://github.com/blueswen
- name: aktools
html_url: https://github.com/akfamily/aktools
stars: 1027
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: 1016
stars: 1155
owner_login: insistence
owner_html_url: https://github.com/insistence
- name: autollm
html_url: https://github.com/viddexa/autollm
stars: 1002
owner_login: viddexa
owner_html_url: https://github.com/viddexa
- name: titiler
html_url: https://github.com/developmentseed/titiler
stars: 999
owner_login: developmentseed
owner_html_url: https://github.com/developmentseed
- name: lanarky
html_url: https://github.com/ajndkr/lanarky
stars: 994
owner_login: ajndkr
owner_html_url: https://github.com/ajndkr
- name: every-pdf
html_url: https://github.com/DDULDDUCK/every-pdf
stars: 985
owner_login: DDULDDUCK
owner_html_url: https://github.com/DDULDDUCK
- name: authx
html_url: https://github.com/yezz123/authx
stars: 1142
owner_login: yezz123
owner_html_url: https://github.com/yezz123
- name: SAG
html_url: https://github.com/Zleap-AI/SAG
stars: 1110
owner_login: Zleap-AI
owner_html_url: https://github.com/Zleap-AI
- name: flock
html_url: https://github.com/Onelevenvy/flock
stars: 1069
owner_login: Onelevenvy
owner_html_url: https://github.com/Onelevenvy
- name: fastapi-observability
html_url: https://github.com/blueswen/fastapi-observability
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: 973
stars: 1061
owner_login: SalesforceAIResearch
owner_html_url: https://github.com/SalesforceAIResearch
- name: fastapi-mail
html_url: https://github.com/sabuhish/fastapi-mail
stars: 964
owner_login: sabuhish
owner_html_url: https://github.com/sabuhish
- name: titiler
html_url: https://github.com/developmentseed/titiler
stars: 1039
owner_login: developmentseed
owner_html_url: https://github.com/developmentseed
- name: every-pdf
html_url: https://github.com/DDULDDUCK/every-pdf
stars: 1017
owner_login: DDULDDUCK
owner_html_url: https://github.com/DDULDDUCK
- name: autollm
html_url: https://github.com/viddexa/autollm
stars: 1005
owner_login: viddexa
owner_html_url: https://github.com/viddexa
- name: lanarky
html_url: https://github.com/ajndkr/lanarky
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: 116
count: 119
avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
url: https://github.com/ceb10n
tokusumi:
@@ -23,16 +23,16 @@ tokusumi:
count: 104
avatarUrl: https://avatars.githubusercontent.com/u/41147016?u=55010621aece725aa702270b54fed829b6a1fe60&v=4
url: https://github.com/tokusumi
hard-coders:
login: hard-coders
count: 102
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=78d12d1acdf853c817700145e73de7fd9e5d068b&v=4
url: https://github.com/hard-coders
hasansezertasan:
login: hasansezertasan
count: 95
avatarUrl: https://avatars.githubusercontent.com/u/13135006?u=99f0b0f0fc47e88e8abb337b4447357939ef93e7&v=4
url: https://github.com/hasansezertasan
hard-coders:
login: hard-coders
count: 93
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
url: https://github.com/hard-coders
alv2017:
login: alv2017
count: 88
@@ -40,7 +40,7 @@ alv2017:
url: https://github.com/alv2017
nazarepiedady:
login: nazarepiedady
count: 86
count: 87
avatarUrl: https://avatars.githubusercontent.com/u/31008635?u=f69ddc4ea8bda3bdfac7aa0e2ea38de282e6ee2d&v=4
url: https://github.com/nazarepiedady
AlertRED:
@@ -48,36 +48,41 @@ AlertRED:
count: 81
avatarUrl: https://avatars.githubusercontent.com/u/15695000?u=f5a4944c6df443030409c88da7d7fa0b7ead985c&v=4
url: https://github.com/AlertRED
tiangolo:
login: tiangolo
count: 78
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
url: https://github.com/tiangolo
Alexandrhub:
login: 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: 59
count: 61
avatarUrl: https://avatars.githubusercontent.com/u/6892179?u=1dca6a22195d6cd1ab20737c0e19a4c55d639472&v=4
url: https://github.com/nilslindemann
mattwang44:
login: mattwang44
count: 59
count: 61
avatarUrl: https://avatars.githubusercontent.com/u/24987826?u=58e37fb3927b9124b458945ac4c97aa0f1062d85&v=4
url: https://github.com/mattwang44
tiangolo:
login: tiangolo
YuriiMotov:
login: YuriiMotov
count: 56
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
url: https://github.com/tiangolo
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=bc48be95c429989224786106b027f3c5e40cc354&v=4
url: https://github.com/YuriiMotov
Laineyzhang55:
login: Laineyzhang55
count: 48
@@ -93,16 +98,16 @@ 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
@@ -118,11 +123,6 @@ Winand:
count: 40
avatarUrl: https://avatars.githubusercontent.com/u/53390?u=bb0e71a2fc3910a8e0ee66da67c33de40ea695f8&v=4
url: https://github.com/Winand
YuriiMotov:
login: YuriiMotov
count: 40
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=b9b13d598dddfab529a52d264df80a900bfe7060&v=4
url: https://github.com/YuriiMotov
solomein-sv:
login: solomein-sv
count: 38
@@ -136,8 +136,13 @@ 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
count: 37
avatarUrl: https://avatars.githubusercontent.com/u/41520940?u=4a9c765af688389d54296845d18b8f6cd6ddf09a&v=4
url: https://github.com/mezgoodle
stlucasgarcia:
login: stlucasgarcia
count: 36
@@ -153,11 +158,6 @@ timothy-jeong:
count: 36
avatarUrl: https://avatars.githubusercontent.com/u/53824764?u=db3d0cea2f5fab64d810113c5039a369699a2774&v=4
url: https://github.com/timothy-jeong
mezgoodle:
login: mezgoodle
count: 35
avatarUrl: https://avatars.githubusercontent.com/u/41520940?u=4a9c765af688389d54296845d18b8f6cd6ddf09a&v=4
url: https://github.com/mezgoodle
rjNemo:
login: rjNemo
count: 34
@@ -173,6 +173,11 @@ akarev0:
count: 33
avatarUrl: https://avatars.githubusercontent.com/u/53393089?u=6e528bb4789d56af887ce6fe237bea4010885406&v=4
url: https://github.com/akarev0
Vincy1230:
login: Vincy1230
count: 33
avatarUrl: https://avatars.githubusercontent.com/u/81342412?u=ab5e256a4077a4a91f3f9cd2115ba80780454cbe&v=4
url: https://github.com/Vincy1230
romashevchenko:
login: romashevchenko
count: 32
@@ -183,11 +188,6 @@ LorhanSohaky:
count: 30
avatarUrl: https://avatars.githubusercontent.com/u/16273730?u=095b66f243a2cd6a0aadba9a095009f8aaf18393&v=4
url: https://github.com/LorhanSohaky
Vincy1230:
login: Vincy1230
count: 30
avatarUrl: https://avatars.githubusercontent.com/u/81342412?u=ab5e256a4077a4a91f3f9cd2115ba80780454cbe&v=4
url: https://github.com/Vincy1230
black-redoc:
login: black-redoc
count: 29
@@ -250,7 +250,7 @@ mycaule:
url: https://github.com/mycaule
Aruelius:
login: Aruelius
count: 24
count: 25
avatarUrl: https://avatars.githubusercontent.com/u/25380989?u=574f8cfcda3ea77a3f81884f6b26a97068e36a9d&v=4
url: https://github.com/Aruelius
wisderfin:
@@ -263,6 +263,11 @@ OzgunCaglarArslan:
count: 24
avatarUrl: https://avatars.githubusercontent.com/u/86166426?v=4
url: https://github.com/OzgunCaglarArslan
ycd:
login: ycd
count: 23
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=f1e7bae394a315da950912c92dc861a8eaf95d4c&v=4
url: https://github.com/ycd
sh0nk:
login: sh0nk
count: 23
@@ -288,11 +293,6 @@ Attsun1031:
count: 20
avatarUrl: https://avatars.githubusercontent.com/u/1175560?v=4
url: https://github.com/Attsun1031
ycd:
login: ycd
count: 20
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=f1e7bae394a315da950912c92dc861a8eaf95d4c&v=4
url: https://github.com/ycd
delhi09:
login: delhi09
count: 20
@@ -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
@@ -443,11 +448,21 @@ impocode:
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/109408819?u=9cdfc5ccb31a2094c520f41b6087012fa9048982&v=4
url: https://github.com/impocode
waketzheng:
login: waketzheng
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/35413830?u=df19e4fd5bb928e7d086e053ef26a46aad23bf84&v=4
url: https://github.com/waketzheng
wesinalves:
login: 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
@@ -461,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
@@ -483,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
@@ -538,21 +548,21 @@ Lufa1u:
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/112495876?u=087658920ed9e74311597bdd921d8d2de939d276&v=4
url: https://github.com/Lufa1u
waketzheng:
login: waketzheng
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/35413830?u=df19e4fd5bb928e7d086e053ef26a46aad23bf84&v=4
url: https://github.com/waketzheng
KNChiu:
login: KNChiu
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/36751646?v=4
url: https://github.com/KNChiu
maru0123-2004:
login: maru0123-2004
Zhongheng-Cheng:
login: Zhongheng-Cheng
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/43961566?u=16ed8603a4d6a4665cb6c53a7aece6f31379b769&v=4
url: https://github.com/maru0123-2004
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
@@ -606,18 +616,18 @@ 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
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/20115018?u=dda090ce9160ef0cd2ff69b1e5ea741283425cba&v=4
url: https://github.com/marcelomarkus
lucasbalieiro:
login: lucasbalieiro
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/37416577?u=dad91601ee4f40458d691774ec439aff308344d7&v=4
avatarUrl: https://avatars.githubusercontent.com/u/37416577?u=d144221c34c08adac8b20e1833d776ffa1c4b1d0&v=4
url: https://github.com/lucasbalieiro
Zhongheng-Cheng:
login: Zhongheng-Cheng
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/95612344?u=a0f7730a3cc7486827965e01a119ad610bda4b0a&v=4
url: https://github.com/Zhongheng-Cheng
RunningIkkyu:
login: RunningIkkyu
count: 9
@@ -668,11 +678,6 @@ yodai-yodai:
count: 9
avatarUrl: https://avatars.githubusercontent.com/u/7031039?u=4f3593f5931892b931a745cfab846eff6e9332e7&v=4
url: https://github.com/yodai-yodai
marcelomarkus:
login: marcelomarkus
count: 9
avatarUrl: https://avatars.githubusercontent.com/u/20115018?u=dda090ce9160ef0cd2ff69b1e5ea741283425cba&v=4
url: https://github.com/marcelomarkus
JoaoGustavoRogel:
login: JoaoGustavoRogel
count: 9
@@ -731,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
@@ -756,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
@@ -788,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
@@ -1163,6 +1173,16 @@ AbolfazlKameli:
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/120686133?u=af8f025278cce0d489007071254e4055df60b78c&v=4
url: https://github.com/AbolfazlKameli
SBillion:
login: 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
@@ -1211,7 +1231,7 @@ phamquanganh31101998:
peebbv6364:
login: peebbv6364
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/26784747?u=75583df215ee01a5cd2dc646aecb81e7dbd33d06&v=4
avatarUrl: https://avatars.githubusercontent.com/u/26784747?u=3bf07017eb4f4fa3639ba8d4ed19980a34bf8f90&v=4
url: https://github.com/peebbv6364
mrparalon:
login: mrparalon
@@ -1251,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
@@ -1413,11 +1433,6 @@ Mohammad222PR:
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/116789737?u=25810a5fe049d2f1618e2e7417cea011cc353ce4&v=4
url: https://github.com/Mohammad222PR
EdmilsonRodrigues:
login: EdmilsonRodrigues
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/62777025?u=217d6f3cd6cc750bb8818a3af7726c8d74eb7c2d&v=4
url: https://github.com/EdmilsonRodrigues
blaisep:
login: blaisep
count: 2
@@ -1583,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
@@ -1821,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
@@ -1838,11 +1858,11 @@ NavesSapnis:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/79222417?u=b5b10291b8e9130ca84fd20f0a641e04ed94b6b1&v=4
url: https://github.com/NavesSapnis
eqsdxr:
login: eqsdxr
isgin01:
login: isgin01
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/157279130?u=7927dc0366995334f9a18c3204a41d3a34d6d96f&v=4
url: https://github.com/eqsdxr
avatarUrl: https://avatars.githubusercontent.com/u/157279130?u=16d6466476cf7dbc55a4cd575b6ea920ebdd81e1&v=4
url: https://github.com/isgin01
syedasamina56:
login: syedasamina56
count: 2

View File

@@ -1,6 +1,6 @@
nilslindemann:
login: nilslindemann
count: 125
count: 130
avatarUrl: https://avatars.githubusercontent.com/u/6892179?u=1dca6a22195d6cd1ab20737c0e19a4c55d639472&v=4
url: https://github.com/nilslindemann
jaystone776:
@@ -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:
@@ -38,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=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
url: https://github.com/hard-coders
Joao-Pedro-P-Holanda:
login: Joao-Pedro-P-Holanda
count: 14
@@ -103,11 +108,11 @@ pablocm83:
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/28315068?u=3310fbb05bb8bfc50d2c48b6cb64ac9ee4a14549&v=4
url: https://github.com/pablocm83
tiangolo:
login: tiangolo
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
url: https://github.com/tiangolo
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
@@ -126,7 +131,7 @@ batlopes:
lucasbalieiro:
login: lucasbalieiro
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/37416577?u=dad91601ee4f40458d691774ec439aff308344d7&v=4
avatarUrl: https://avatars.githubusercontent.com/u/37416577?u=d144221c34c08adac8b20e1833d776ffa1c4b1d0&v=4
url: https://github.com/lucasbalieiro
Alexandrhub:
login: Alexandrhub
@@ -286,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
@@ -356,13 +361,8 @@ 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
YuriiMotov:
login: YuriiMotov
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=b9b13d598dddfab529a52d264df80a900bfe7060&v=4
url: https://github.com/YuriiMotov
izaguerreiro:
login: izaguerreiro
count: 2
@@ -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

@@ -6,7 +6,7 @@ Tests added here will be seen by all designers of language specific prompts.
Use as follows:
* Have a language specific prompt `docs/{language code}/llm-prompt.md`.
* Have a language specific prompt - `docs/{language code}/llm-prompt.md`.
* Do a fresh translation of this document into your desired target language (see e.g. the `translate-page` command of the `translate.py`). This will create the translation under `docs/{language code}/docs/_llm-test.md`.
* Check if things are okay in the translation.
* If necessary, improve your language specific prompt, the general prompt, or the English document.

View File

@@ -4,7 +4,7 @@ FastAPI is built on top of **Pydantic**, and I have been showing you how to use
But FastAPI also supports using <a href="https://docs.python.org/3/library/dataclasses.html" class="external-link" target="_blank">`dataclasses`</a> the same way:
{* ../../docs_src/dataclasses/tutorial001_py310.py hl[1,6:11,18:19] *}
{* ../../docs_src/dataclasses_/tutorial001_py310.py hl[1,6:11,18:19] *}
This is still supported thanks to **Pydantic**, as it has <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">internal support for `dataclasses`</a>.
@@ -32,7 +32,7 @@ But if you have a bunch of dataclasses laying around, this is a nice trick to us
You can also use `dataclasses` in the `response_model` parameter:
{* ../../docs_src/dataclasses/tutorial002_py310.py hl[1,6:12,18] *}
{* ../../docs_src/dataclasses_/tutorial002_py310.py hl[1,6:12,18] *}
The dataclass will be automatically converted to a Pydantic dataclass.
@@ -48,7 +48,7 @@ In some cases, you might still have to use Pydantic's version of `dataclasses`.
In that case, you can simply swap the standard `dataclasses` with `pydantic.dataclasses`, which is a drop-in replacement:
{* ../../docs_src/dataclasses/tutorial003_py310.py hl[1,4,7:10,13:16,22:24,27] *}
{* ../../docs_src/dataclasses_/tutorial003_py310.py hl[1,4,7:10,13:16,22:24,27] *}
1. We still import `field` from standard `dataclasses`.

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

@@ -6,44 +6,20 @@ First, you might want to see the basic ways to [help FastAPI and get help](help-
If you already cloned the <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">fastapi repository</a> and you want to deep dive in the code, here are some guidelines to set up your environment.
### Virtual environment
Follow the instructions to create and activate a [virtual environment](virtual-environments.md){.internal-link target=_blank} for the internal code of `fastapi`.
### Install requirements
After activating the environment, install the required packages:
//// tab | `pip`
Create a virtual environment and install the required packages with <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a>:
<div class="termy">
```console
$ pip install -r requirements.txt
$ uv sync --extra all
---> 100%
```
</div>
////
//// tab | `uv`
If you have <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a>:
<div class="termy">
```console
$ uv pip install -r requirements.txt
---> 100%
```
</div>
////
It will install all the dependencies and your local FastAPI in your local environment.
### Using your local FastAPI
@@ -56,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 this included `requirements.txt` 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 inside the `requirements.txt` file, the local version of FastAPI is marked to be installed in "editable" mode, with the `-e` option.
That is because `uv sync --extra all` will install the local version of FastAPI in "editable" mode by default.
///
@@ -201,252 +177,81 @@ 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.
#### Tips and guidelines
#### Translation PRs
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.
These translations are normally still reviewed by native speakers, and here's where you can help!
* 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>.
* 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.
* 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.
///
#### Subscribe to Notifications for Your Language
* 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.
* If you translate pages, add a single pull request per page translated. That will make it much easier for others to review it.
* 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.
#### 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

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

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

@@ -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_py39.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: 187 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@@ -117,6 +117,12 @@ The key features are:
---
## FastAPI mini documentary { #fastapi-mini-documentary }
There's a <a href="https://www.youtube.com/watch?v=mpR8ngthqiE" class="external-link" target="_blank">FastAPI mini documentary</a> released at the end of 2025, you can watch it online:
<a href="https://www.youtube.com/watch?v=mpR8ngthqiE" target="_blank"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini Documentary"></a>
## **Typer**, the FastAPI of CLIs { #typer-the-fastapi-of-clis }
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
@@ -155,8 +161,6 @@ $ pip install "fastapi[standard]"
Create a file `main.py` with:
```Python
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@@ -168,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}
```
@@ -177,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()
@@ -191,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}
```
@@ -282,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
@@ -294,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("/")
@@ -303,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

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

@@ -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,6 +7,155 @@ hide:
## Latest Changes
## 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).
* 🌐 Update translation prompts. PR [#14619](https://github.com/fastapi/fastapi/pull/14619) by [@tiangolo](https://github.com/tiangolo).
* 🔨 Update LLM translation script to guide reviewers to change the prompt. PR [#14614](https://github.com/fastapi/fastapi/pull/14614) by [@tiangolo](https://github.com/tiangolo).
* 👷 Do not run translations on cron while finishing updating existing languages. PR [#14613](https://github.com/fastapi/fastapi/pull/14613) by [@tiangolo](https://github.com/tiangolo).
* 🔥 Remove test variants for Pydantic v1 in test_request_params. PR [#14612](https://github.com/fastapi/fastapi/pull/14612) by [@tiangolo](https://github.com/tiangolo).
* 🔥 Remove Pydantic v1 specific test variants. PR [#14611](https://github.com/fastapi/fastapi/pull/14611) by [@tiangolo](https://github.com/tiangolo).
## 0.128.0
### Breaking Changes
* Drop support for `pydantic.v1`. PR [#14609](https://github.com/fastapi/fastapi/pull/14609) by [@tiangolo](https://github.com/tiangolo).
### Internal
* ✅ Run performance tests only on Pydantic v2. PR [#14608](https://github.com/fastapi/fastapi/pull/14608) by [@tiangolo](https://github.com/tiangolo).
## 0.127.1
### Refactors
* 🔊 Add a custom `FastAPIDeprecationWarning`. PR [#14605](https://github.com/fastapi/fastapi/pull/14605) by [@tiangolo](https://github.com/tiangolo).
### Docs
* 📝 Add documentary to website. PR [#14600](https://github.com/fastapi/fastapi/pull/14600) by [@tiangolo](https://github.com/tiangolo).
### Translations
* 🌐 Update translations for de (update-outdated). PR [#14602](https://github.com/fastapi/fastapi/pull/14602) by [@nilslindemann](https://github.com/nilslindemann).
* 🌐 Update translations for de (update-outdated). PR [#14581](https://github.com/fastapi/fastapi/pull/14581) by [@nilslindemann](https://github.com/nilslindemann).
### Internal
* 🔧 Update pre-commit to use local Ruff instead of hook. PR [#14604](https://github.com/fastapi/fastapi/pull/14604) by [@tiangolo](https://github.com/tiangolo).
* ✅ Add missing tests for code examples. PR [#14569](https://github.com/fastapi/fastapi/pull/14569) by [@YuriiMotov](https://github.com/YuriiMotov).
* 👷 Remove `lint` job from `test` CI workflow. PR [#14593](https://github.com/fastapi/fastapi/pull/14593) by [@YuriiMotov](https://github.com/YuriiMotov).
* 👷 Update secrets check. PR [#14592](https://github.com/fastapi/fastapi/pull/14592) by [@tiangolo](https://github.com/tiangolo).
* 👷 Run CodSpeed tests in parallel to other tests to speed up CI. PR [#14586](https://github.com/fastapi/fastapi/pull/14586) by [@tiangolo](https://github.com/tiangolo).
* 🔨 Update scripts and pre-commit to autofix files. PR [#14585](https://github.com/fastapi/fastapi/pull/14585) by [@tiangolo](https://github.com/tiangolo).
## 0.127.0
### Breaking Changes
* 🔊 Add deprecation warnings when using `pydantic.v1`. PR [#14583](https://github.com/fastapi/fastapi/pull/14583) by [@tiangolo](https://github.com/tiangolo).
### Translations
* 🔧 Add LLM prompt file for Korean, generated from the existing translations. PR [#14546](https://github.com/fastapi/fastapi/pull/14546) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Add LLM prompt file for Japanese, generated from the existing translations. PR [#14545](https://github.com/fastapi/fastapi/pull/14545) by [@tiangolo](https://github.com/tiangolo).
### Internal
* ⬆️ Upgrade OpenAI model for translations to gpt-5.2. PR [#14579](https://github.com/fastapi/fastapi/pull/14579) by [@tiangolo](https://github.com/tiangolo).
## 0.126.0
### Upgrades
@@ -181,7 +330,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
@@ -316,7 +465,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
@@ -2544,7 +2693,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).
@@ -3920,7 +4069,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

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

View File

@@ -102,15 +102,16 @@ Of course, you can also declare additional query parameters whenever you need, a
As, by default, singular values are interpreted as query parameters, you don't have to explicitly add a `Query`, you can just do:
```Python
q: str | None = None
```
Or in Python 3.9:
```Python
q: Union[str, None] = None
```
Or in Python 3.10 and above:
```Python
q: str | None = None
```
For example:

View File

@@ -52,7 +52,7 @@ In these cases, it could make sense to store the tags in an `Enum`.
You can add a `summary` and `description`:
{* ../../docs_src/path_operation_configuration/tutorial003_py310.py hl[18:19] *}
{* ../../docs_src/path_operation_configuration/tutorial003_py310.py hl[17:18] *}
## Description from docstring { #description-from-docstring }
@@ -70,7 +70,7 @@ It will be used in the interactive docs:
You can specify the response description with the parameter `response_description`:
{* ../../docs_src/path_operation_configuration/tutorial005_py310.py hl[19] *}
{* ../../docs_src/path_operation_configuration/tutorial005_py310.py hl[18] *}
/// info

View File

@@ -317,10 +317,16 @@ extra:
name: de - Deutsch
- link: /es/
name: es - español
- link: /ja/
name: ja - 日本語
- link: /ko/
name: ko - 한국어
- link: /pt/
name: pt - português
- link: /ru/
name: ru - русский язык
- link: /uk/
name: uk - українська мова
extra_css:
- css/termynal.css
- css/custom.css

View File

@@ -1,17 +1,17 @@
# Archivo de prueba de LLM { #llm-test-file }
Este documento prueba si el <abbr title="Large Language Model Modelo de lenguaje grande">LLM</abbr>, que traduce la documentación, entiende el `general_prompt` en `scripts/translate.py` y el prompt específico del idioma en `docs/{language code}/llm-prompt.md`. El prompt específico del idioma se agrega al final de `general_prompt`.
Este documento prueba si el <abbr title="Large Language Model - Modelo de lenguaje grande">LLM</abbr>, que traduce la documentación, entiende el `general_prompt` en `scripts/translate.py` y el prompt específico del idioma en `docs/{language code}/llm-prompt.md`. El prompt específico del idioma se agrega al final de `general_prompt`.
Las pruebas añadidas aquí serán vistas por todas las personas que diseñan prompts específicos del idioma.
Úsalo de la siguiente manera:
* Ten un prompt específico del idioma `docs/{language code}/llm-prompt.md`.
* Ten un prompt específico del idioma - `docs/{language code}/llm-prompt.md`.
* Haz una traducción fresca de este documento a tu idioma destino (mira, por ejemplo, el comando `translate-page` de `translate.py`). Esto creará la traducción en `docs/{language code}/docs/_llm-test.md`.
* Comprueba si todo está bien en la traducción.
* Revisa si las cosas están bien en la traducción.
* Si es necesario, mejora tu prompt específico del idioma, el prompt general, o el documento en inglés.
* Luego corrige manualmente los problemas restantes en la traducción para que sea una buena traducción.
* Vuelve a traducir, teniendo la buena traducción en su lugar. El resultado ideal sería que el LLM ya no hiciera cambios a la traducción. Eso significa que el prompt general y tu prompt específico del idioma están tan bien como pueden estar (a veces hará algunos cambios aparentemente aleatorios; la razón es que <a href="https://doublespeak.chat/#/handbook#deterministic-output" class="external-link" target="_blank">los LLMs no son algoritmos deterministas</a>).
* Vuelve a traducir, teniendo la buena traducción en su lugar. El resultado ideal sería que el LLM ya no hiciera cambios a la traducción. Eso significa que el prompt general y tu prompt específico del idioma están tan bien como pueden estar (A veces hará algunos cambios aparentemente aleatorios; la razón es que <a href="https://doublespeak.chat/#/handbook#deterministic-output" class="external-link" target="_blank">los LLMs no son algoritmos deterministas</a>).
Las pruebas:
@@ -23,7 +23,7 @@ Este es un fragmento de código: `foo`. Y este es otro fragmento de código: `ba
////
//// tab | Información
//// tab | Info
El contenido de los fragmentos de código debe dejarse tal cual.
@@ -45,7 +45,7 @@ El LLM probablemente traducirá esto mal. Lo interesante es si mantiene la tradu
////
//// tab | Información
//// tab | Info
La persona que diseña el prompt puede elegir si quiere convertir comillas neutras a comillas tipográficas. También está bien dejarlas como están.
@@ -67,7 +67,7 @@ Hardcore: `Yesterday, my friend wrote: "If you spell incorrectly correctly, you
////
//// tab | Información
//// tab | Info
... Sin embargo, las comillas dentro de fragmentos de código deben quedarse tal cual.
@@ -112,7 +112,7 @@ works(foo="bar") # Esto funciona 🎉
////
//// tab | Información
//// tab | Info
El código en bloques de código no debe modificarse, con la excepción de los comentarios.
@@ -154,7 +154,7 @@ Algo de texto
////
//// tab | Información
//// tab | Info
Las pestañas y los bloques `Info`/`Note`/`Warning`/etc. deben tener la traducción de su título añadida después de una barra vertical (`|`).
@@ -181,7 +181,7 @@ El texto del enlace debe traducirse, la dirección del enlace debe apuntar a la
////
//// tab | Información
//// tab | Info
Los enlaces deben traducirse, pero su dirección debe permanecer sin cambios. Una excepción son los enlaces absolutos a páginas de la documentación de FastAPI. En ese caso deben enlazar a la traducción.
@@ -197,10 +197,10 @@ Aquí algunas cosas envueltas en elementos HTML "abbr" (algunas son inventadas):
### El abbr da una frase completa { #the-abbr-gives-a-full-phrase }
* <abbr title="Getting Things Done Hacer las cosas">GTD</abbr>
* <abbr title="less than menor que"><code>lt</code></abbr>
* <abbr title="XML Web Token Token web XML">XWT</abbr>
* <abbr title="Parallel Server Gateway Interface Interfaz de pasarela de servidor paralela">PSGI</abbr>
* <abbr title="Getting Things Done - Hacer las cosas">GTD</abbr>
* <abbr title="less than - menor que"><code>lt</code></abbr>
* <abbr title="XML Web Token - Token web XML">XWT</abbr>
* <abbr title="Parallel Server Gateway Interface - Interfaz de pasarela de servidor paralela">PSGI</abbr>
### El abbr da una explicación { #the-abbr-gives-an-explanation }
@@ -209,12 +209,12 @@ Aquí algunas cosas envueltas en elementos HTML "abbr" (algunas son inventadas):
### El abbr da una frase completa y una explicación { #the-abbr-gives-a-full-phrase-and-an-explanation }
* <abbr title="Mozilla Developer Network Red de Desarrolladores de Mozilla: documentación para desarrolladores, escrita por la gente de Firefox">MDN</abbr>
* <abbr title="Input/Output Entrada/Salida: lectura o escritura de disco, comunicaciones de red.">I/O</abbr>.
* <abbr title="Mozilla Developer Network - Red de Desarrolladores de Mozilla: documentación para desarrolladores, escrita por la gente de Firefox">MDN</abbr>
* <abbr title="Input/Output: lectura o escritura de disco, comunicaciones de red.">I/O</abbr>.
////
//// tab | Información
//// tab | Info
Los atributos "title" de los elementos "abbr" se traducen siguiendo instrucciones específicas.
@@ -242,7 +242,7 @@ Hola de nuevo.
////
//// tab | Información
//// tab | Info
La única regla estricta para los encabezados es que el LLM deje la parte del hash dentro de llaves sin cambios, lo que asegura que los enlaces no se rompan.
@@ -355,7 +355,7 @@ Para instrucciones específicas del idioma, mira p. ej. la sección `### Heading
* los headers
* el header de autorización
* el header `Authorization`
* el header Forwarded
* el header forwarded
* el sistema de inyección de dependencias
* la dependencia
@@ -368,7 +368,7 @@ Para instrucciones específicas del idioma, mira p. ej. la sección `### Heading
* paralelismo
* multiprocesamiento
* la variable de entorno
* la env var
* la variable de entorno
* el `PATH`
* la variable `PATH`
@@ -433,7 +433,7 @@ Para instrucciones específicas del idioma, mira p. ej. la sección `### Heading
* el motor de plantillas
* la anotación de tipos
* la anotación de tipos
* las anotaciones de tipos
* el worker del servidor
* el worker de Uvicorn
@@ -468,7 +468,7 @@ Para instrucciones específicas del idioma, mira p. ej. la sección `### Heading
* el ítem
* el paquete
* el lifespan
* el bloqueo
* el lock
* el middleware
* la aplicación móvil
* el módulo
@@ -494,7 +494,7 @@ Para instrucciones específicas del idioma, mira p. ej. la sección `### Heading
////
//// tab | Información
//// tab | Info
Esta es una lista no completa y no normativa de términos (mayormente) técnicos vistos en la documentación. Puede ayudar a la persona que diseña el prompt a identificar para qué términos el LLM necesita una mano. Por ejemplo cuando sigue revirtiendo una buena traducción a una traducción subóptima. O cuando tiene problemas conjugando/declinando un término en tu idioma.

View File

@@ -4,7 +4,7 @@ FastAPI está construido sobre **Pydantic**, y te he estado mostrando cómo usar
Pero FastAPI también soporta el uso de <a href="https://docs.python.org/3/library/dataclasses.html" class="external-link" target="_blank">`dataclasses`</a> de la misma manera:
{* ../../docs_src/dataclasses/tutorial001_py310.py hl[1,6:11,18:19] *}
{* ../../docs_src/dataclasses_/tutorial001_py310.py hl[1,6:11,18:19] *}
Esto sigue siendo soportado gracias a **Pydantic**, ya que tiene <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">soporte interno para `dataclasses`</a>.
@@ -32,7 +32,7 @@ Pero si tienes un montón de dataclasses por ahí, este es un buen truco para us
También puedes usar `dataclasses` en el parámetro `response_model`:
{* ../../docs_src/dataclasses/tutorial002_py310.py hl[1,6:12,18] *}
{* ../../docs_src/dataclasses_/tutorial002_py310.py hl[1,6:12,18] *}
El dataclass será automáticamente convertido a un dataclass de Pydantic.
@@ -48,7 +48,7 @@ En algunos casos, todavía podrías tener que usar la versión de `dataclasses`
En ese caso, simplemente puedes intercambiar los `dataclasses` estándar con `pydantic.dataclasses`, que es un reemplazo directo:
{* ../../docs_src/dataclasses/tutorial003_py310.py hl[1,4,7:10,13:16,22:24,27] *}
{* ../../docs_src/dataclasses_/tutorial003_py310.py hl[1,4,7:10,13:16,22:24,27] *}
1. Todavía importamos `field` de los `dataclasses` estándar.

View File

@@ -10,7 +10,7 @@ Si no eres un "experto" en OpenAPI, probablemente no necesites esto.
Puedes establecer el `operationId` de OpenAPI para ser usado en tu *path operation* con el parámetro `operation_id`.
Tienes que asegurarte de que sea único para cada operación.
Tendrías que asegurarte de que sea único para cada operación.
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
@@ -46,7 +46,7 @@ Para excluir una *path operation* del esquema OpenAPI generado (y por lo tanto,
Puedes limitar las líneas usadas del docstring de una *path operation function* para OpenAPI.
Añadir un `\f` (un carácter de separación de página escapado) hace que **FastAPI** trunque la salida usada para OpenAPI en este punto.
Añadir un `\f` (un carácter "form feed" escapado) hace que **FastAPI** trunque la salida usada para OpenAPI en este punto.
No aparecerá en la documentación, pero otras herramientas (como Sphinx) podrán usar el resto.
@@ -141,9 +141,9 @@ Podrías hacer eso con `openapi_extra`:
{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
En este ejemplo, no declaramos ningún modelo Pydantic. De hecho, el cuerpo del request ni siquiera se <abbr title="convertido de algún formato plano, como bytes, a objetos de Python">parse</abbr> como JSON, se lee directamente como `bytes`, y la función `magic_data_reader()` sería la encargada de parsearlo de alguna manera.
En este ejemplo, no declaramos ningún modelo Pydantic. De hecho, el request body ni siquiera se <abbr title="converted from some plain format, like bytes, into Python objects - convertido de algún formato plano, como bytes, a objetos de Python">parse</abbr> como JSON, se lee directamente como `bytes`, y la función `magic_data_reader()` sería la encargada de parsearlo de alguna manera.
Sin embargo, podemos declarar el esquema esperado para el cuerpo del request.
Sin embargo, podemos declarar el esquema esperado para el request body.
### Tipo de contenido personalizado de OpenAPI { #custom-openapi-content-type }
@@ -153,48 +153,16 @@ Y podrías hacer esto incluso si el tipo de datos en el request no es JSON.
Por ejemplo, en esta aplicación no usamos la funcionalidad integrada de FastAPI para extraer el JSON Schema de los modelos Pydantic ni la validación automática para JSON. De hecho, estamos declarando el tipo de contenido del request como YAML, no JSON:
//// tab | Pydantic v2
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
////
//// tab | Pydantic v1
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[15:20, 22] *}
////
/// info | Información
En la versión 1 de Pydantic el método para obtener el JSON Schema para un modelo se llamaba `Item.schema()`, en la versión 2 de Pydantic, el método se llama `Item.model_json_schema()`.
///
Sin embargo, aunque no estamos usando la funcionalidad integrada por defecto, aún estamos usando un modelo Pydantic para generar manualmente el JSON Schema para los datos que queremos recibir en YAML.
Luego usamos el request directamente, y extraemos el cuerpo como `bytes`. Esto significa que FastAPI ni siquiera intentará parsear la carga útil del request como JSON.
Y luego en nuestro código, parseamos ese contenido YAML directamente, y nuevamente estamos usando el mismo modelo Pydantic para validar el contenido YAML:
//// tab | Pydantic v2
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
////
//// tab | Pydantic v1
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[24:31] *}
////
/// info | Información
En la versión 1 de Pydantic el método para parsear y validar un objeto era `Item.parse_obj()`, en la versión 2 de Pydantic, el método se llama `Item.model_validate()`.
///
/// tip | Consejo
Aquí reutilizamos el mismo modelo Pydantic.

View File

@@ -46,12 +46,6 @@ $ pip install "fastapi[all]"
</div>
/// info | Información
En Pydantic v1 venía incluido con el paquete principal. Ahora se distribuye como este paquete independiente para que puedas elegir si instalarlo o no si no necesitas esa funcionalidad.
///
### Crear el objeto `Settings` { #create-the-settings-object }
Importa `BaseSettings` de Pydantic y crea una sub-clase, muy similar a un modelo de Pydantic.
@@ -60,31 +54,15 @@ De la misma forma que con los modelos de Pydantic, declaras atributos de clase c
Puedes usar todas las mismas funcionalidades de validación y herramientas que usas para los modelos de Pydantic, como diferentes tipos de datos y validaciones adicionales con `Field()`.
//// tab | Pydantic v2
{* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *}
////
//// tab | Pydantic v1
/// info | Información
En Pydantic v1 importarías `BaseSettings` directamente desde `pydantic` en lugar de desde `pydantic_settings`.
///
{* ../../docs_src/settings/tutorial001_pv1_py39.py hl[2,5:8,11] *}
////
/// tip | Consejo
Si quieres algo rápido para copiar y pegar, no uses este ejemplo, usa el último más abajo.
///
Luego, cuando creas una instance de esa clase `Settings` (en este caso, en el objeto `settings`), Pydantic leerá las variables de entorno de una manera indiferente a mayúsculas y minúsculas, por lo que una variable en mayúsculas `APP_NAME` aún será leída para el atributo `app_name`.
Luego, cuando creas un instance de esa clase `Settings` (en este caso, en el objeto `settings`), Pydantic leerá las variables de entorno de una manera indiferente a mayúsculas y minúsculas, por lo que una variable en mayúsculas `APP_NAME` aún será leída para el atributo `app_name`.
Luego convertirá y validará los datos. Así que, cuando uses ese objeto `settings`, tendrás datos de los tipos que declaraste (por ejemplo, `items_per_user` será un `int`).
@@ -110,7 +88,7 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.p
/// tip | Consejo
Para establecer múltiples variables de entorno para un solo comando, simplemente sepáralas con un espacio y ponlas todas antes del comando.
Para establecer múltiples env vars para un solo comando, simplemente sepáralas con un espacio y ponlas todas antes del comando.
///
@@ -150,7 +128,7 @@ Proveniente del ejemplo anterior, tu archivo `config.py` podría verse como:
{* ../../docs_src/settings/app02_an_py39/config.py hl[10] *}
Nota que ahora no creamos una instance por defecto `settings = Settings()`.
Nota que ahora no creamos un instance por defecto `settings = Settings()`.
### El archivo principal de la app { #the-main-app-file }
@@ -172,11 +150,11 @@ Y luego podemos requerirlo desde la *path operation function* como una dependenc
### Configuraciones y pruebas { #settings-and-testing }
Luego sería muy fácil proporcionar un objeto de configuraciones diferente durante las pruebas al sobrescribir una dependencia para `get_settings`:
Luego sería muy fácil proporcionar un objeto de configuraciones diferente durante las pruebas al crear una sobrescritura de dependencia para `get_settings`:
{* ../../docs_src/settings/app02_an_py39/test_main.py hl[9:10,13,21] *}
En la dependencia sobreescrita establecemos un nuevo valor para el `admin_email` al crear el nuevo objeto `Settings`, y luego devolvemos ese nuevo objeto.
En la sobrescritura de dependencia establecemos un nuevo valor para el `admin_email` al crear el nuevo objeto `Settings`, y luego devolvemos ese nuevo objeto.
Luego podemos probar que se está usando.
@@ -215,8 +193,6 @@ APP_NAME="ChimichangApp"
Y luego actualizar tu `config.py` con:
//// tab | Pydantic v2
{* ../../docs_src/settings/app03_an_py39/config.py hl[9] *}
/// tip | Consejo
@@ -225,26 +201,6 @@ El atributo `model_config` se usa solo para configuración de Pydantic. Puedes l
///
////
//// tab | Pydantic v1
{* ../../docs_src/settings/app03_an_py39/config_pv1.py hl[9:10] *}
/// tip | Consejo
La clase `Config` se usa solo para configuración de Pydantic. Puedes leer más en <a href="https://docs.pydantic.dev/1.10/usage/model_config/" class="external-link" target="_blank">Pydantic Model Config</a>.
///
////
/// info | Información
En la versión 1 de Pydantic la configuración se hacía en una clase interna `Config`, en la versión 2 de Pydantic se hace en un atributo `model_config`. Este atributo toma un `dict`, y para obtener autocompletado y errores en línea, puedes importar y usar `SettingsConfigDict` para definir ese `dict`.
///
Aquí definimos la configuración `env_file` dentro de tu clase Pydantic `Settings`, y establecemos el valor en el nombre del archivo con el archivo dotenv que queremos usar.
### Creando el `Settings` solo una vez con `lru_cache` { #creating-the-settings-only-once-with-lru-cache }
@@ -331,7 +287,7 @@ participant execute as Ejecutar función
end
```
En el caso de nuestra dependencia `get_settings()`, la función ni siquiera toma argumentos, por lo que siempre devolve el mismo valor.
En el caso de nuestra dependencia `get_settings()`, la función ni siquiera toma argumentos, por lo que siempre devuelve el mismo valor.
De esa manera, se comporta casi como si fuera solo una variable global. Pero como usa una función de dependencia, entonces podemos sobrescribirla fácilmente para las pruebas.

View File

@@ -35,7 +35,7 @@ Dependiendo de tu caso de uso, podrías preferir usar un paquete diferente, pero
Aquí tienes una pequeña vista previa de cómo podrías integrar Strawberry con FastAPI:
{* ../../docs_src/graphql/tutorial001_py39.py hl[3,22,25] *}
{* ../../docs_src/graphql_/tutorial001_py39.py hl[3,22,25] *}
Puedes aprender más sobre Strawberry en la <a href="https://strawberry.rocks/" class="external-link" target="_blank">documentación de Strawberry</a>.

View File

@@ -2,21 +2,23 @@
Si tienes una app de FastAPI antigua, podrías estar usando Pydantic versión 1.
FastAPI ha tenido compatibilidad con Pydantic v1 o v2 desde la versión 0.100.0.
FastAPI versión 0.100.0 tenía compatibilidad con Pydantic v1 o v2. Usaba la que tuvieras instalada.
Si tenías instalado Pydantic v2, lo usaba. Si en cambio tenías Pydantic v1, usaba ese.
FastAPI versión 0.119.0 introdujo compatibilidad parcial con Pydantic v1 desde dentro de Pydantic v2 (como `pydantic.v1`), para facilitar la migración a v2.
Pydantic v1 está deprecado y su soporte se eliminará en las próximas versiones de FastAPI, deberías migrar a Pydantic v2. Así obtendrás las funcionalidades, mejoras y correcciones más recientes.
FastAPI 0.126.0 eliminó la compatibilidad con Pydantic v1, aunque siguió soportando `pydantic.v1` por un poquito más de tiempo.
/// warning | Advertencia
Además, el equipo de Pydantic dejó de dar soporte a Pydantic v1 para las versiones más recientes de Python, comenzando con Python 3.14.
El equipo de Pydantic dejó de dar soporte a Pydantic v1 para las versiones más recientes de Python, comenzando con **Python 3.14**.
Esto incluye `pydantic.v1`, que ya no está soportado en Python 3.14 y superiores.
Si quieres usar las funcionalidades más recientes de Python, tendrás que asegurarte de usar Pydantic v2.
///
Si tienes una app de FastAPI antigua con Pydantic v1, aquí te muestro cómo migrarla a Pydantic v2 y las nuevas funcionalidades en FastAPI 0.119.0 para ayudarte con una migración gradual.
Si tienes una app de FastAPI antigua con Pydantic v1, aquí te muestro cómo migrarla a Pydantic v2, y las **funcionalidades en FastAPI 0.119.0** para ayudarte con una migración gradual.
## Guía oficial { #official-guide }
@@ -44,9 +46,9 @@ Después de esto, puedes ejecutar los tests y revisa si todo funciona. Si es as
## Pydantic v1 en v2 { #pydantic-v1-in-v2 }
Pydantic v2 incluye todo lo de Pydantic v1 como un submódulo `pydantic.v1`.
Pydantic v2 incluye todo lo de Pydantic v1 como un submódulo `pydantic.v1`. Pero esto ya no está soportado en versiones por encima de Python 3.13.
Esto significa que puedes instalar la versión más reciente de Pydantic v2 e importar y usar los componentes viejos de Pydantic v1 desde ese submódulo, como si tuvieras instalado el Pydantic v1 antiguo.
Esto significa que puedes instalar la versión más reciente de Pydantic v2 e importar y usar los componentes viejos de Pydantic v1 desde este submódulo, como si tuvieras instalado el Pydantic v1 antiguo.
{* ../../docs_src/pydantic_v1_in_v2/tutorial001_an_py310.py hl[1,4] *}
@@ -66,7 +68,7 @@ Ten en cuenta que, como el equipo de Pydantic ya no da soporte a Pydantic v1 en
### Pydantic v1 y v2 en la misma app { #pydantic-v1-and-v2-on-the-same-app }
No está soportado por Pydantic tener un modelo de Pydantic v2 con sus propios campos definidos como modelos de Pydantic v1 o viceversa.
**No está soportado** por Pydantic tener un modelo de Pydantic v2 con sus propios campos definidos como modelos de Pydantic v1 o viceversa.
```mermaid
graph TB
@@ -106,7 +108,7 @@ graph TB
style V2Field fill:#f9fff3
```
En algunos casos, incluso es posible tener modelos de Pydantic v1 y v2 en la misma path operation de tu app de FastAPI:
En algunos casos, incluso es posible tener modelos de Pydantic v1 y v2 en la misma **path operation** de tu app de FastAPI:
{* ../../docs_src/pydantic_v1_in_v2/tutorial003_an_py310.py hl[2:3,6,12,21:22] *}
@@ -122,12 +124,12 @@ Si necesitas usar algunas de las herramientas específicas de FastAPI para pará
/// tip | Consejo
Primero prueba con `bump-pydantic`; si tus tests pasan y eso funciona, entonces terminaste con un solo comando. ✨
Primero prueba con `bump-pydantic`, si tus tests pasan y eso funciona, entonces terminaste con un solo comando. ✨
///
Si `bump-pydantic` no funciona para tu caso, puedes usar la compatibilidad de modelos Pydantic v1 y v2 en la misma app para hacer la migración a Pydantic v2 de forma gradual.
Si `bump-pydantic` no funciona para tu caso de uso, puedes usar la compatibilidad de modelos Pydantic v1 y v2 en la misma app para hacer la migración a Pydantic v2 de forma gradual.
Podrías primero actualizar Pydantic para usar la última versión 2 y cambiar los imports para usar `pydantic.v1` para todos tus modelos.
Podrías primero actualizar Pydantic para usar la última versión 2, y cambiar los imports para usar `pydantic.v1` para todos tus modelos.
Luego puedes empezar a migrar tus modelos de Pydantic v1 a v2 por grupos, en pasos graduales. 🚶

View File

@@ -1,6 +1,6 @@
# Separación de Esquemas OpenAPI para Entrada y Salida o No { #separate-openapi-schemas-for-input-and-output-or-not }
Al usar **Pydantic v2**, el OpenAPI generado es un poco más exacto y **correcto** que antes. 😎
Desde que se lanzó **Pydantic v2**, el OpenAPI generado es un poco más exacto y **correcto** que antes. 😎
De hecho, en algunos casos, incluso tendrá **dos JSON Schemas** en OpenAPI para el mismo modelo Pydantic, para entrada y salida, dependiendo de si tienen **valores por defecto**.
@@ -85,7 +85,7 @@ Probablemente el caso principal para esto es si ya tienes algún código cliente
En ese caso, puedes desactivar esta funcionalidad en **FastAPI**, con el parámetro `separate_input_output_schemas=False`.
/// info | Información
/// info
El soporte para `separate_input_output_schemas` fue agregado en FastAPI `0.102.0`. 🤓
@@ -100,5 +100,3 @@ Y ahora habrá un único esquema para entrada y salida para el modelo, solo `Ite
<div class="screenshot">
<img src="/img/tutorial/separate-openapi-schemas/image05.png">
</div>
Este es el mismo comportamiento que en Pydantic v1. 🤓

View File

@@ -93,13 +93,13 @@ Las funcionalidades clave son:
"_Estoy súper emocionado con **FastAPI**. ¡Es tan divertido!_"
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">host del podcast Python Bytes</a></strong> <a href="https://x.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a> host del podcast</strong> <a href="https://x.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
---
"_Honestamente, lo que has construido parece súper sólido y pulido. En muchos aspectos, es lo que quería que **Hug** fuera; es realmente inspirador ver a alguien construir eso._"
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">creador de Hug</a></strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> creador</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
---
@@ -117,6 +117,12 @@ Las funcionalidades clave son:
---
## Mini documental de FastAPI { #fastapi-mini-documentary }
Hay un <a href="https://www.youtube.com/watch?v=mpR8ngthqiE" class="external-link" target="_blank">mini documental de FastAPI</a> lanzado a finales de 2025, puedes verlo online:
<a href="https://www.youtube.com/watch?v=mpR8ngthqiE" target="_blank"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini Documentary"></a>
## **Typer**, el FastAPI de las CLIs { #typer-the-fastapi-of-clis }
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
@@ -268,7 +274,7 @@ Verás la documentación interactiva automática de la API (proporcionada por <a
![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
### Documentación de API Alternativa { #alternative-api-docs }
### Documentación alternativa de la API { #alternative-api-docs }
Y ahora, ve a <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
@@ -276,7 +282,7 @@ Verás la documentación alternativa automática (proporcionada por <a href="htt
![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
## Actualización del Ejemplo { #example-upgrade }
## Actualización del ejemplo { #example-upgrade }
Ahora modifica el archivo `main.py` para recibir un body desde un request `PUT`.
@@ -314,7 +320,7 @@ def update_item(item_id: int, item: Item):
El servidor `fastapi dev` debería recargarse automáticamente.
### Actualización de la Documentación Interactiva de la API { #interactive-api-docs-upgrade }
### Actualización de la documentación interactiva de la API { #interactive-api-docs-upgrade }
Ahora ve a <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
@@ -330,7 +336,7 @@ Ahora ve a <a href="http://127.0.0.1:8000/docs" class="external-link" target="_b
![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-05-swagger-04.png)
### Actualización de la Documentación Alternativa de la API { #alternative-api-docs-upgrade }
### Actualización de la documentación alternativa de la API { #alternative-api-docs-upgrade }
Y ahora, ve a <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
@@ -393,13 +399,13 @@ Volviendo al ejemplo de código anterior, **FastAPI**:
* Validará que haya un `item_id` en el path para requests `GET` y `PUT`.
* Validará que el `item_id` sea del tipo `int` para requests `GET` y `PUT`.
* Si no lo es, el cliente verá un error útil y claro.
* Comprobará si hay un parámetro de query opcional llamado `q` (como en `http://127.0.0.1:8000/items/foo?q=somequery`) para requests `GET`.
* Revisa si hay un parámetro de query opcional llamado `q` (como en `http://127.0.0.1:8000/items/foo?q=somequery`) para requests `GET`.
* Como el parámetro `q` está declarado con `= None`, es opcional.
* Sin el `None` sería requerido (como lo es el body en el caso con `PUT`).
* Para requests `PUT` a `/items/{item_id}`, leerá el body como JSON:
* Comprobará que tiene un atributo requerido `name` que debe ser un `str`.
* Comprobará que tiene un atributo requerido `price` que debe ser un `float`.
* Comprobará que tiene un atributo opcional `is_offer`, que debe ser un `bool`, si está presente.
* Revisa que tiene un atributo requerido `name` que debe ser un `str`.
* Revisa que tiene un atributo requerido `price` que debe ser un `float`.
* Revisa que tiene un atributo opcional `is_offer`, que debe ser un `bool`, si está presente.
* Todo esto también funcionaría para objetos JSON profundamente anidados.
* Convertirá de y a JSON automáticamente.
* Documentará todo con OpenAPI, que puede ser usado por:

View File

@@ -56,7 +56,7 @@ from app.routers import items
La misma estructura de archivos con comentarios:
```
```bash
.
├── app # "app" es un paquete de Python
│   ├── __init__.py # este archivo hace que "app" sea un "paquete de Python"
@@ -185,7 +185,7 @@ El resultado final es que los paths de item son ahora:
* Todos incluirán las `responses` predefinidas.
* Todas estas *path operations* tendrán la lista de `dependencies` evaluadas/ejecutadas antes de ellas.
* Si también declaras dependencias en una *path operation* específica, **también se ejecutarán**.
* Las dependencias del router se ejecutan primero, luego las [dependencias en el decorador](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, y luego las dependencias de parámetros normales.
* Las dependencias del router se ejecutan primero, luego las [`dependencies` en el decorador](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, y luego las dependencias de parámetros normales.
* También puedes agregar [dependencias de `Security` con `scopes`](../advanced/security/oauth2-scopes.md){.internal-link target=_blank}.
/// tip | Consejo
@@ -214,7 +214,7 @@ Así que usamos un import relativo con `..` para las dependencias:
/// tip | Consejo
Si sabes perfectamente cómo funcionan los imports, continúa a la siguiente sección.
Si sabes perfectamente cómo funcionan los imports, continúa a la siguiente sección abajo.
///
@@ -271,7 +271,7 @@ eso significaría:
Eso se referiría a algún paquete arriba de `app/`, con su propio archivo `__init__.py`, etc. Pero no tenemos eso. Así que, eso lanzaría un error en nuestro ejemplo. 🚨
Pero ahora sabes cómo funciona, para que puedas usar imports relativos en tus propias aplicaciones sin importar cuán complejas sean. 🤓
Pero ahora sabes cómo funciona, para que puedas usar imports relativos en tus propias apps sin importar cuán complejas sean. 🤓
### Agregar algunos `tags`, `responses`, y `dependencies` personalizados { #add-some-custom-tags-responses-and-dependencies }
@@ -283,7 +283,7 @@ Pero aún podemos agregar _más_ `tags` que se aplicarán a una *path operation*
/// tip | Consejo
Esta última *path operation* tendrá la combinación de tags: `["items", "custom"]`.
Esta última path operation tendrá la combinación de tags: `["items", "custom"]`.
Y también tendrá ambas responses en la documentación, una para `404` y otra para `403`.
@@ -301,7 +301,7 @@ Y como la mayor parte de tu lógica ahora vivirá en su propio módulo específi
### Importar `FastAPI` { #import-fastapi }
Importas y creas una clase `FastAPI` como de costumbre.
Importas y creas una clase `FastAPI` como normalmente.
Y podemos incluso declarar [dependencias globales](dependencies/global-dependencies.md){.internal-link target=_blank} que se combinarán con las dependencias para cada `APIRouter`:
@@ -398,7 +398,7 @@ Incluirá todas las rutas de ese router como parte de ella.
En realidad creará internamente una *path operation* para cada *path operation* que fue declarada en el `APIRouter`.
Así, detrás de escena, funcionará como si todo fuera la misma única aplicación.
Así, detrás de escena, funcionará como si todo fuera la misma única app.
///
@@ -430,20 +430,20 @@ Podemos declarar todo eso sin tener que modificar el `APIRouter` original pasand
De esa manera, el `APIRouter` original permanecerá sin modificar, por lo que aún podemos compartir ese mismo archivo `app/internal/admin.py` con otros proyectos en la organización.
El resultado es que, en nuestra aplicación, cada una de las *path operations* del módulo `admin` tendrá:
El resultado es que, en nuestra app, cada una de las *path operations* del módulo `admin` tendrá:
* El prefix `/admin`.
* El tag `admin`.
* La dependencia `get_token_header`.
* La response `418`. 🍵
Pero eso solo afectará a ese `APIRouter` en nuestra aplicación, no en ningún otro código que lo utilice.
Pero eso solo afectará a ese `APIRouter` en nuestra app, no en ningún otro código que lo utilice.
Así, por ejemplo, otros proyectos podrían usar el mismo `APIRouter` con un método de autenticación diferente.
### Incluir una *path operation* { #include-a-path-operation }
También podemos agregar *path operations* directamente a la aplicación de `FastAPI`.
También podemos agregar *path operations* directamente a la app de `FastAPI`.
Aquí lo hacemos... solo para mostrar que podemos 🤷:
@@ -461,13 +461,13 @@ Los `APIRouter`s no están "montados", no están aislados del resto de la aplica
Esto se debe a que queremos incluir sus *path operations* en el esquema de OpenAPI y las interfaces de usuario.
Como no podemos simplemente aislarlos y "montarlos" independientemente del resto, se "clonan" las *path operations* (se vuelven a crear), no se incluyen directamente.
Como no podemos simplemente aislarlos y "montarlos" independientemente del resto, las *path operations* se "clonan" (se vuelven a crear), no se incluyen directamente.
///
## Revisa la documentación automática de la API { #check-the-automatic-api-docs }
Ahora, ejecuta tu aplicación:
Ahora, ejecuta tu app:
<div class="termy">
@@ -481,7 +481,7 @@ $ fastapi dev app/main.py
Y abre la documentación en <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
Verás la documentación automática de la API, incluyendo los paths de todos los submódulos, usando los paths correctos (y prefijos) y las tags correctas:
Verás la documentación automática de la API, incluyendo los paths de todos los submódulos, usando los paths correctos (y prefijos) y los tags correctos:
<img src="/img/tutorial/bigger-applications/image01.png">
@@ -501,4 +501,4 @@ De la misma manera que puedes incluir un `APIRouter` en una aplicación `FastAPI
router.include_router(other_router)
```
Asegúrate de hacerlo antes de incluir `router` en la aplicación de `FastAPI`, para que las *path operations* de `other_router` también se incluyan.
Asegúrate de hacerlo antes de incluir `router` en la app de `FastAPI`, para que las *path operations* de `other_router` también se incluyan.

View File

@@ -1,4 +1,4 @@
# Cuerpo - Actualizaciones { #body-updates }
# Body - Actualizaciones { #body-updates }
## Actualización reemplazando con `PUT` { #update-replacing-with-put }
@@ -50,14 +50,6 @@ Si quieres recibir actualizaciones parciales, es muy útil usar el parámetro `e
Como `item.model_dump(exclude_unset=True)`.
/// info | Información
En Pydantic v1 el método se llamaba `.dict()`, fue deprecado (pero aún soportado) en Pydantic v2, y renombrado a `.model_dump()`.
Los ejemplos aquí usan `.dict()` para compatibilidad con Pydantic v1, pero deberías usar `.model_dump()` si puedes usar Pydantic v2.
///
Eso generaría un `dict` solo con los datos que se establecieron al crear el modelo `item`, excluyendo los valores por defecto.
Luego puedes usar esto para generar un `dict` solo con los datos que se establecieron (enviados en el request), omitiendo los valores por defecto:
@@ -68,14 +60,6 @@ Luego puedes usar esto para generar un `dict` solo con los datos que se establec
Ahora, puedes crear una copia del modelo existente usando `.model_copy()`, y pasar el parámetro `update` con un `dict` que contenga los datos a actualizar.
/// info | Información
En Pydantic v1 el método se llamaba `.copy()`, fue deprecado (pero aún soportado) en Pydantic v2, y renombrado a `.model_copy()`.
Los ejemplos aquí usan `.copy()` para compatibilidad con Pydantic v1, pero deberías usar `.model_copy()` si puedes usar Pydantic v2.
///
Como `stored_item_model.model_copy(update=update_data)`:
{* ../../docs_src/body_updates/tutorial002_py310.py hl[33] *}
@@ -90,9 +74,9 @@ En resumen, para aplicar actualizaciones parciales deberías:
* Generar un `dict` sin valores por defecto del modelo de entrada (usando `exclude_unset`).
* De esta manera puedes actualizar solo los valores realmente establecidos por el usuario, en lugar de sobrescribir valores ya almacenados con valores por defecto en tu modelo.
* Crear una copia del modelo almacenado, actualizando sus atributos con las actualizaciones parciales recibidas (usando el parámetro `update`).
* Convertir el modelo copiado en algo que pueda almacenarse en tu base de datos (por ejemplo, usando el `jsonable_encoder`).
* Convertir el modelo copiado en algo que pueda almacenarse en tu DB (por ejemplo, usando el `jsonable_encoder`).
* Esto es comparable a usar el método `.model_dump()` del modelo de nuevo, pero asegura (y convierte) los valores a tipos de datos que pueden convertirse a JSON, por ejemplo, `datetime` a `str`.
* Guardar los datos en tu base de datos.
* Guardar los datos en tu DB.
* Devolver el modelo actualizado.
{* ../../docs_src/body_updates/tutorial002_py310.py hl[28:35] *}

View File

@@ -32,7 +32,8 @@ Usa tipos estándar de Python para todos los atributos:
{* ../../docs_src/body/tutorial001_py310.py hl[5:9] *}
Al igual que al declarar parámetros de query, cuando un atributo del modelo tiene un valor por defecto, no es obligatorio. De lo contrario, es obligatorio. Usa `None` para hacerlo opcional.
Al igual que al declarar parámetros de query, cuando un atributo del modelo tiene un valor por defecto, no es obligatorio. De lo contrario, es obligatorio. Usa `None` para hacerlo solo opcional.
Por ejemplo, el modelo anterior declara un “`object`” JSON (o `dict` en Python) como:
@@ -127,14 +128,6 @@ Dentro de la función, puedes acceder a todos los atributos del objeto modelo di
{* ../../docs_src/body/tutorial002_py310.py *}
/// info | Información
En Pydantic v1 el método se llamaba `.dict()`, se marcó como obsoleto (pero sigue soportado) en Pydantic v2, y se renombró a `.model_dump()`.
Los ejemplos aquí usan `.dict()` por compatibilidad con Pydantic v1, pero deberías usar `.model_dump()` si puedes usar Pydantic v2.
///
## Request body + parámetros de path { #request-body-path-parameters }
Puedes declarar parámetros de path y request body al mismo tiempo.
@@ -143,6 +136,7 @@ Puedes declarar parámetros de path y request body al mismo tiempo.
{* ../../docs_src/body/tutorial003_py310.py hl[15:16] *}
## Request body + path + parámetros de query { #request-body-path-query-parameters }
También puedes declarar parámetros de **body**, **path** y **query**, todos al mismo tiempo.
@@ -155,7 +149,7 @@ Los parámetros de la función se reconocerán de la siguiente manera:
* Si el parámetro también se declara en el **path**, se utilizará como un parámetro de path.
* Si el parámetro es de un **tipo singular** (como `int`, `float`, `str`, `bool`, etc.), se interpretará como un parámetro de **query**.
* Si el parámetro se declara como del tipo de un **modelo de Pydantic**, se interpretará como un **request body**.
* Si el parámetro se declara como del tipo de un **modelo de Pydantic**, se interpretará como un **body** de request.
/// note | Nota

View File

@@ -22,21 +22,13 @@ Aquí tienes una idea general de cómo podrían ser los modelos con sus campos d
{* ../../docs_src/extra_models/tutorial001_py310.py hl[7,9,14,20,22,27:28,31:33,38:39] *}
/// info | Información
### Acerca de `**user_in.model_dump()` { #about-user-in-model-dump }
En Pydantic v1 el método se llamaba `.dict()`, fue deprecado (pero aún soportado) en Pydantic v2, y renombrado a `.model_dump()`.
Los ejemplos aquí usan `.dict()` para compatibilidad con Pydantic v1, pero deberías usar `.model_dump()` en su lugar si puedes usar Pydantic v2.
///
### Acerca de `**user_in.dict()` { #about-user-in-dict }
#### `.dict()` de Pydantic { #pydantics-dict }
#### `.model_dump()` de Pydantic { #pydantics-model-dump }
`user_in` es un modelo Pydantic de la clase `UserIn`.
Los modelos Pydantic tienen un método `.dict()` que devuelve un `dict` con los datos del modelo.
Los modelos Pydantic tienen un método `.model_dump()` que devuelve un `dict` con los datos del modelo.
Así que, si creamos un objeto Pydantic `user_in` como:
@@ -47,7 +39,7 @@ user_in = UserIn(username="john", password="secret", email="john.doe@example.com
y luego llamamos a:
```Python
user_dict = user_in.dict()
user_dict = user_in.model_dump()
```
ahora tenemos un `dict` con los datos en la variable `user_dict` (es un `dict` en lugar de un objeto modelo Pydantic).
@@ -58,7 +50,7 @@ Y si llamamos a:
print(user_dict)
```
obtendremos un `dict` de Python con:
obtendríamos un `dict` de Python con:
```Python
{
@@ -103,20 +95,20 @@ UserInDB(
#### Un modelo Pydantic a partir del contenido de otro { #a-pydantic-model-from-the-contents-of-another }
Como en el ejemplo anterior obtuvimos `user_dict` de `user_in.dict()`, este código:
Como en el ejemplo anterior obtuvimos `user_dict` de `user_in.model_dump()`, este código:
```Python
user_dict = user_in.dict()
user_dict = user_in.model_dump()
UserInDB(**user_dict)
```
sería equivalente a:
```Python
UserInDB(**user_in.dict())
UserInDB(**user_in.model_dump())
```
...porque `user_in.dict()` es un `dict`, y luego hacemos que Python lo "desempaquete" al pasarlo a `UserInDB` con el prefijo `**`.
...porque `user_in.model_dump()` es un `dict`, y luego hacemos que Python lo "desempaquete" al pasarlo a `UserInDB` con el prefijo `**`.
Así, obtenemos un modelo Pydantic a partir de los datos en otro modelo Pydantic.
@@ -125,7 +117,7 @@ Así, obtenemos un modelo Pydantic a partir de los datos en otro modelo Pydantic
Y luego agregando el argumento de palabra clave adicional `hashed_password=hashed_password`, como en:
```Python
UserInDB(**user_in.dict(), hashed_password=hashed_password)
UserInDB(**user_in.model_dump(), hashed_password=hashed_password)
```
...termina siendo como:
@@ -156,7 +148,7 @@ Y estos modelos están compartiendo muchos de los datos y duplicando nombres y t
Podríamos hacerlo mejor.
Podemos declarar un modelo `UserBase` que sirva como base para nuestros otros modelos. Y luego podemos hacer subclases de ese modelo que heredan sus atributos (anotaciones de tipos, validación, etc).
Podemos declarar un modelo `UserBase` que sirva como base para nuestros otros modelos. Y luego podemos hacer subclases de ese modelo que heredan sus atributos (declaraciones de tipos, validación, etc).
Toda la conversión de datos, validación, documentación, etc. seguirá funcionando normalmente.
@@ -180,20 +172,19 @@ Al definir una <a href="https://docs.pydantic.dev/latest/concepts/types/#unions"
{* ../../docs_src/extra_models/tutorial003_py310.py hl[1,14:15,18:20,33] *}
### `Union` en Python 3.10 { #union-in-python-3-10 }
En este ejemplo pasamos `Union[PlaneItem, CarItem]` como el valor del argumento `response_model`.
Porque lo estamos pasando como un **valor a un argumento** en lugar de ponerlo en **anotaciones de tipos**, tenemos que usar `Union` incluso en Python 3.10.
Porque lo estamos pasando como un **valor a un argumento** en lugar de ponerlo en una **anotación de tipos**, tenemos que usar `Union` incluso en Python 3.10.
Si estuviera en anotaciones de tipos podríamos haber usado la barra vertical, como:
Si estuviera en una anotación de tipos podríamos haber usado la barra vertical, como:
```Python
some_variable: PlaneItem | CarItem
```
Pero si ponemos eso en la asignación `response_model=PlaneItem | CarItem` obtendríamos un error, porque Python intentaría realizar una **operación inválida** entre `PlaneItem` y `CarItem` en lugar de interpretar eso como anotaciones de tipos.
Pero si ponemos eso en la asignación `response_model=PlaneItem | CarItem` obtendríamos un error, porque Python intentaría realizar una **operación inválida** entre `PlaneItem` y `CarItem` en lugar de interpretar eso como una anotación de tipos.
## Lista de modelos { #list-of-models }
@@ -203,7 +194,6 @@ Para eso, usa el `typing.List` estándar de Python (o simplemente `list` en Pyth
{* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *}
## Response con `dict` arbitrario { #response-with-arbitrary-dict }
También puedes declarar un response usando un `dict` arbitrario plano, declarando solo el tipo de las claves y valores, sin usar un modelo Pydantic.
@@ -214,7 +204,6 @@ En este caso, puedes usar `typing.Dict` (o solo `dict` en Python 3.9 y posterior
{* ../../docs_src/extra_models/tutorial005_py39.py hl[6] *}
## Recapitulación { #recap }
Usa múltiples modelos Pydantic y hereda libremente para cada caso.

View File

@@ -109,7 +109,7 @@ FastAPI ahora:
## Alternativa (antigua): `Query` como valor por defecto { #alternative-old-query-as-the-default-value }
Versiones anteriores de FastAPI (antes de <abbr title="antes de 2023-03">0.95.0</abbr>) requerían que usaras `Query` como el valor por defecto de tu parámetro, en lugar de ponerlo en `Annotated`, hay una alta probabilidad de que veas código usándolo alrededor, así que te lo explicaré.
Versiones anteriores de FastAPI (antes de <abbr title="before 2023-03 - antes de 2023-03">0.95.0</abbr>) requerían que usaras `Query` como el valor por defecto de tu parámetro, en lugar de ponerlo en `Annotated`, hay una alta probabilidad de que veas código usándolo alrededor, así que te lo explicaré.
/// tip | Consejo
@@ -192,7 +192,7 @@ También puedes agregar un parámetro `min_length`:
## Agregar expresiones regulares { #add-regular-expressions }
Puedes definir un <abbr title="Una expresión regular, regex o regexp es una secuencia de caracteres que define un patrón de búsqueda para strings.">expresión regular</abbr> `pattern` que el parámetro debe coincidir:
Puedes definir una <abbr title="Una expresión regular, regex o regexp es una secuencia de caracteres que define un patrón de búsqueda para strings.">expresión regular</abbr> `pattern` que el parámetro debe coincidir:
{* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *}
@@ -206,20 +206,6 @@ Si te sientes perdido con todas estas ideas de **"expresión regular"**, no te p
Ahora sabes que cuando las necesites puedes usarlas en **FastAPI**.
### Pydantic v1 `regex` en lugar de `pattern` { #pydantic-v1-regex-instead-of-pattern }
Antes de la versión 2 de Pydantic y antes de FastAPI 0.100.0, el parámetro se llamaba `regex` en lugar de `pattern`, pero ahora está en desuso.
Todavía podrías ver algo de código que lo usa:
//// tab | Pydantic v1
{* ../../docs_src/query_params_str_validations/tutorial004_regex_an_py310.py hl[11] *}
////
Pero que sepas que esto está deprecado y debería actualizarse para usar el nuevo parámetro `pattern`. 🤓
## Valores por defecto { #default-values }
Puedes, por supuesto, usar valores por defecto diferentes de `None`.
@@ -280,7 +266,7 @@ Entonces, con una URL como:
http://localhost:8000/items/?q=foo&q=bar
```
recibirías los múltiples valores del *query parameter* `q` (`foo` y `bar`) en una `list` de Python dentro de tu *path operation function*, en el *parámetro de función* `q`.
recibirías los múltiples valores de los *query parameters* `q` (`foo` y `bar`) en una `list` de Python dentro de tu *path operation function*, en el *parámetro de función* `q`.
Entonces, el response a esa URL sería:
@@ -386,7 +372,7 @@ Entonces puedes declarar un `alias`, y ese alias será usado para encontrar el v
Ahora digamos que ya no te gusta este parámetro.
Tienes que dejarlo allí por un tiempo porque hay clientes usándolo, pero quieres que la documentación lo muestre claramente como <abbr title="obsoleto, se recomienda no usarlo">deprecated</abbr>.
Tienes que dejarlo allí por un tiempo porque hay clientes usándolo, pero quieres que la documentación lo muestre claramente como <abbr title="obsolete, recommended not to use it - obsoleto, se recomienda no usarlo">deprecated</abbr>.
Luego pasa el parámetro `deprecated=True` a `Query`:
@@ -416,7 +402,7 @@ Pydantic también tiene <a href="https://docs.pydantic.dev/latest/concepts/valid
///
Por ejemplo, este validador personalizado comprueba que el ID del ítem empiece con `isbn-` para un número de libro <abbr title="International Standard Book Number Número Estándar Internacional de Libro">ISBN</abbr> o con `imdb-` para un ID de URL de película de <abbr title="IMDB (Internet Movie Database) es un sitio web con información sobre películas">IMDB</abbr>:
Por ejemplo, este validador personalizado comprueba que el ID del ítem empiece con `isbn-` para un número de libro <abbr title="ISBN means International Standard Book Number - ISBN significa International Standard Book Number">ISBN</abbr> o con `imdb-` para un ID de URL de película de <abbr title="IMDB (Internet Movie Database) is a website with information about movies - IMDB (Internet Movie Database) es un sitio web con información sobre películas">IMDB</abbr>:
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
@@ -450,7 +436,7 @@ Pero si te da curiosidad este ejemplo de código específico y sigues entretenid
#### Un ítem aleatorio { #a-random-item }
Con `data.items()` obtenemos un <abbr title="Algo que podemos iterar con un for, como una list, set, etc.">objeto iterable</abbr> con tuplas que contienen la clave y el valor para cada elemento del diccionario.
Con `data.items()` obtenemos un <abbr title="Algo que podemos iterar con un for loop, como una list, set, etc.">objeto iterable</abbr> con tuplas que contienen la clave y el valor para cada elemento del diccionario.
Convertimos este objeto iterable en una `list` propiamente dicha con `list(data.items())`.

View File

@@ -2,7 +2,7 @@
Puedes declarar el tipo utilizado para el response anotando el **tipo de retorno** de la *path operation function*.
Puedes utilizar **anotaciones de tipos** de la misma manera que lo harías para datos de entrada en **parámetros** de función, puedes utilizar modelos de Pydantic, list, diccionarios, valores escalares como enteros, booleanos, etc.
Puedes utilizar **anotaciones de tipos** de la misma manera que lo harías para datos de entrada en **parámetros** de función, puedes utilizar modelos de Pydantic, lists, diccionarios, valores escalares como enteros, booleanos, etc.
{* ../../docs_src/response_model/tutorial001_01_py310.py hl[16,21] *}
@@ -27,7 +27,7 @@ Por ejemplo, podrías querer **devolver un diccionario** u objeto de base de dat
Si añadiste la anotación del tipo de retorno, las herramientas y editores se quejarían con un error (correcto) diciéndote que tu función está devolviendo un tipo (por ejemplo, un dict) que es diferente de lo que declaraste (por ejemplo, un modelo de Pydantic).
En esos casos, puedes usar el parámetro del decorador de path operation `response_model` en lugar del tipo de retorno.
En esos casos, puedes usar el parámetro del *decorador de path operation* `response_model` en lugar del tipo de retorno.
Puedes usar el parámetro `response_model` en cualquiera de las *path operations*:
@@ -153,7 +153,7 @@ Primero vamos a ver cómo los editores, mypy y otras herramientas verían esto.
`BaseUser` tiene los campos base. Luego `UserIn` hereda de `BaseUser` y añade el campo `password`, por lo que incluirá todos los campos de ambos modelos.
Anotamos el tipo de retorno de la función como `BaseUser`, pero en realidad estamos devolviendo un instance de `UserIn`.
Anotamos el tipo de retorno de la función como `BaseUser`, pero en realidad estamos devolviendo un `UserIn` instance.
El editor, mypy y otras herramientas no se quejarán de esto porque, en términos de tipificación, `UserIn` es una subclase de `BaseUser`, lo que significa que es un tipo *válido* cuando se espera algo que es un `BaseUser`.
@@ -252,20 +252,6 @@ Entonces, si envías un request a esa *path operation* para el ítem con ID `foo
/// info | Información
En Pydantic v1 el método se llamaba `.dict()`, fue deprecado (pero aún soportado) en Pydantic v2, y renombrado a `.model_dump()`.
Los ejemplos aquí usan `.dict()` para compatibilidad con Pydantic v1, pero deberías usar `.model_dump()` en su lugar si puedes usar Pydantic v2.
///
/// info | Información
FastAPI usa el método `.dict()` del modelo de Pydantic con <a href="https://docs.pydantic.dev/1.10/usage/exporting_models/#modeldict" class="external-link" target="_blank">su parámetro `exclude_unset`</a> para lograr esto.
///
/// info | Información
También puedes usar:
* `response_model_exclude_defaults=True`

View File

@@ -8,35 +8,13 @@ Aquí tienes varias formas de hacerlo.
Puedes declarar `examples` para un modelo de Pydantic que se añadirá al JSON Schema generado.
//// tab | Pydantic v2
{* ../../docs_src/schema_extra_example/tutorial001_py310.py hl[13:24] *}
////
Esa información extra se añadirá tal cual al **JSON Schema** resultante para ese modelo, y se usará en la documentación de la API.
//// tab | Pydantic v1
Puedes usar el atributo `model_config` que toma un `dict` como se describe en <a href="https://docs.pydantic.dev/latest/api/config/" class="external-link" target="_blank">la documentación de Pydantic: Configuración</a>.
{* ../../docs_src/schema_extra_example/tutorial001_pv1_py310.py hl[13:23] *}
////
Esa información extra se añadirá tal cual al **JSON Schema** generado para ese modelo, y se usará en la documentación de la API.
//// tab | Pydantic v2
En Pydantic versión 2, usarías el atributo `model_config`, que toma un `dict` como se describe en <a href="https://docs.pydantic.dev/latest/api/config/" class="external-link" target="_blank">la documentación de Pydantic: Configuración</a>.
Puedes establecer `"json_schema_extra"` con un `dict` que contenga cualquier dato adicional que desees que aparezca en el JSON Schema generado, incluyendo `examples`.
////
//// tab | Pydantic v1
En Pydantic versión 1, usarías una clase interna `Config` y `schema_extra`, como se describe en <a href="https://docs.pydantic.dev/1.10/usage/schema/#schema-customization" class="external-link" target="_blank">la documentación de Pydantic: Personalización de Esquema</a>.
Puedes establecer `schema_extra` con un `dict` que contenga cualquier dato adicional que desees que aparezca en el JSON Schema generado, incluyendo `examples`.
////
Puedes establecer `"json_schema_extra"` con un `dict` que contenga cualquier dato adicional que te gustaría que aparezca en el JSON Schema generado, incluyendo `examples`.
/// tip | Consejo
@@ -50,7 +28,7 @@ Por ejemplo, podrías usarlo para añadir metadatos para una interfaz de usuario
OpenAPI 3.1.0 (usado desde FastAPI 0.99.0) añadió soporte para `examples`, que es parte del estándar de **JSON Schema**.
Antes de eso, solo soportaba la palabra clave `example` con un solo ejemplo. Eso aún es soportado por OpenAPI 3.1.0, pero está obsoleto y no es parte del estándar de JSON Schema. Así que se recomienda migrar de `example` a `examples`. 🤓
Antes de eso, solo soportaba la palabra clave `example` con un solo ejemplo. Eso aún es soportado por OpenAPI 3.1.0, pero está obsoleto y no es parte del estándar de JSON Schema. Así que se te anima a migrar `example` a `examples`. 🤓
Puedes leer más al final de esta página.
@@ -94,7 +72,7 @@ Por supuesto, también puedes pasar múltiples `examples`:
{* ../../docs_src/schema_extra_example/tutorial004_an_py310.py hl[23:38] *}
Cuando haces esto, los ejemplos serán parte del **JSON Schema** interno para esos datos de body.
Cuando haces esto, los ejemplos serán parte del **JSON Schema** interno para esos datos del body.
Sin embargo, al <abbr title="2023-08-26">momento de escribir esto</abbr>, Swagger UI, la herramienta encargada de mostrar la interfaz de documentación, no soporta mostrar múltiples ejemplos para los datos en **JSON Schema**. Pero lee más abajo para una solución alternativa.
@@ -203,17 +181,17 @@ Debido a eso, las versiones de FastAPI anteriores a 0.99.0 todavía usaban versi
### `examples` de Pydantic y FastAPI { #pydantic-and-fastapi-examples }
Cuando añades `examples` dentro de un modelo de Pydantic, usando `schema_extra` o `Field(examples=["algo"])`, ese ejemplo se añade al **JSON Schema** para ese modelo de Pydantic.
Cuando añades `examples` dentro de un modelo de Pydantic, usando `schema_extra` o `Field(examples=["something"])`, ese ejemplo se añade al **JSON Schema** para ese modelo de Pydantic.
Y ese **JSON Schema** del modelo de Pydantic se incluye en el **OpenAPI** de tu API, y luego se usa en la interfaz de documentación.
En las versiones de FastAPI antes de 0.99.0 (0.99.0 y superior usan el nuevo OpenAPI 3.1.0) cuando usabas `example` o `examples` con cualquiera de las otras utilidades (`Query()`, `Body()`, etc.) esos ejemplos no se añadían al JSON Schema que describe esos datos (ni siquiera a la propia versión de JSON Schema de OpenAPI), se añadían directamente a la declaración de la *path operation* en OpenAPI (fuera de las partes de OpenAPI que usan JSON Schema).
En las versiones de FastAPI antes de 0.99.0 (0.99.0 y superiores usan el nuevo OpenAPI 3.1.0) cuando usabas `example` o `examples` con cualquiera de las otras utilidades (`Query()`, `Body()`, etc.) esos ejemplos no se añadían al JSON Schema que describe esos datos (ni siquiera a la propia versión de JSON Schema de OpenAPI), se añadían directamente a la declaración de la *path operation* en OpenAPI (fuera de las partes de OpenAPI que usan JSON Schema).
Pero ahora que FastAPI 0.99.0 y superiores usa OpenAPI 3.1.0, que usa JSON Schema 2020-12, y Swagger UI 5.0.0 y superiores, todo es más consistente y los ejemplos se incluyen en JSON Schema.
### Swagger UI y `examples` específicos de OpenAPI { #swagger-ui-and-openapi-specific-examples }
Ahora, como Swagger UI no soportaba múltiples ejemplos de JSON Schema (a fecha de 2023-08-26), los usuarios no tenían una forma de mostrar múltiples ejemplos en los documentos.
Ahora, como Swagger UI no soportaba múltiples ejemplos de JSON Schema (a fecha de 2023-08-26), los usuarios no tenían una forma de mostrar múltiples ejemplos en la documentación.
Para resolver eso, FastAPI `0.103.0` **añadió soporte** para declarar el mismo viejo campo **específico de OpenAPI** `examples` con el nuevo parámetro `openapi_examples`. 🤓

View File

@@ -6,123 +6,127 @@ Language code: fr.
### Grammar to use when talking to the reader
Use the formal grammar (use «vous» instead of «tu»).
Use the formal grammar (use `vous` instead of `tu`).
Additionally, in instructional sentences, prefer the present tense for obligations:
- Prefer `vous devez …` over `vous devrez …`, unless the English source explicitly refers to a future requirement.
- When translating “make sure (that) … is …”, prefer the indicative after `vous assurer que` (e.g. `Vous devez vous assurer qu'il est …`) instead of the subjunctive (e.g. `qu'il soit …`).
### Quotes
1) Convert neutral double quotes («"») and English double typographic quotes («“» and «”») to French guillemets (««» and «»»).
- Convert neutral double quotes (`"`) to French guillemets (`«` and `»`).
2) In the French docs, guillemets are written without extra spaces: use «texte», not « texte ».
3) Do not convert quotes inside code blocks, inline code, paths, URLs, or anything wrapped in backticks.
- Do not convert quotes inside code blocks, inline code, paths, URLs, or anything wrapped in backticks.
Examples:
Source (English):
Source (English):
«««
"Hello world"
“Hello Universe”
"He said: 'Hello'"
"The module is `__main__`"
»»»
```
"Hello world"
“Hello Universe”
"He said: 'Hello'"
"The module is `__main__`"
```
Result (French):
Result (French):
«««
«Hello world»
«Hello Universe»
«He said: 'Hello'»
«The module is `__main__`»
»»»
```
"Hello world"
Hello Universe
"He said: 'Hello'"
"The module is `__main__`"
```
### Ellipsis
1) Make sure there is a space between an ellipsis and a word following or preceding the ellipsis.
- Make sure there is a space between an ellipsis and a word following or preceding the ellipsis.
Examples:
Source (English):
Source (English):
«««
...as we intended.
...this would work:
...etc.
others...
More to come...
»»»
```
...as we intended.
...this would work:
...etc.
others...
More to come...
```
Result (French):
Result (French):
«««
... comme prévu.
... cela fonctionnerait :
... etc.
D'autres ...
La suite ...
»»»
```
... comme prévu.
... cela fonctionnerait :
... etc.
D'autres ...
La suite ...
```
2) This does not apply in URLs, code blocks, and code snippets. Do not remove or add spaces there.
- This does not apply in URLs, code blocks, and code snippets. Do not remove or add spaces there.
### Headings
1) Prefer translating headings using the infinitive form (as is common in the existing French docs): «Créer…», «Utiliser…», «Ajouter…».
- Prefer translating headings using the infinitive form (as is common in the existing French docs): `Créer…`, `Utiliser…`, `Ajouter…`.
2) For headings that are instructions written in imperative in English (e.g. Go check …), keep them in imperative in French, using the formal grammar (e.g. «Allez voir …»).
3) Keep heading punctuation as in the source. In particular, keep occurrences of literal « - » (space-hyphen-space) as « - » (the existing French docs use a hyphen here).
- For headings that are instructions written in imperative in English (e.g. `Go check …`), keep them in imperative in French, using the formal grammar (e.g. `Allez voir …`).
### French instructions about technical terms
Do not try to translate everything. In particular, keep common programming terms when that is the established usage in the French docs (e.g. «framework», «endpoint», «plug-in», «payload»). Use French where the existing docs already consistently use French (e.g. «requête», «réponse»).
Do not try to translate everything. In particular, keep common programming terms (e.g. `framework`, `endpoint`, `plug-in`, `payload`).
Keep class names, function names, modules, file names, and CLI commands unchanged.
### List of English terms and their preferred French translations
Below is a list of English terms and their preferred French translations, separated by a colon («:»). Use these translations, do not use your own. If an existing translation does not use these terms, update it to use them.
Below is a list of English terms and their preferred French translations, separated by a colon (:). Use these translations, do not use your own. If an existing translation does not use these terms, update it to use them.
* «/// note | Technical Details»: «/// note | Détails techniques»
* «/// note»: «/// note | Remarque»
* «/// tip»: «/// tip | Astuce»
* «/// warning»: «/// warning | Attention»
* «/// check»: «/// check | vérifier»
* «/// info»: «/// info»
- /// note | Technical Details»: /// note | Détails techniques
- /// note: /// note | Remarque
- /// tip: /// tip | Astuce
- /// warning: /// warning | Alertes
- /// check: /// check | Vérifications
- /// info: /// info
* «the docs»: «les documents»
* «the documentation»: «la documentation»
- the docs: les documents
- the documentation: la documentation
* «framework»: «framework» (do not translate to «cadre»)
* «performance»: «performance»
- Exclude from OpenAPI: Exclusion d'OpenAPI
* «type hints»: «annotations de type»
* «type annotations»: «annotations de type»
- framework: framework (do not translate to cadre)
- performance: performance
* «autocomplete»: «autocomplétion»
* «autocompletion»: «autocomplétion»
- type hints: annotations de type
- type annotations: annotations de type
* «the request» (what the client sends to the server): «la requête»
* «the response» (what the server sends back to the client): «la réponse»
- autocomplete: autocomplétion
- autocompletion: autocomplétion
* «the request body»: «le corps de la requête»
* «the response body»: «le corps de la réponse»
- the request (what the client sends to the server): la requête
- the response (what the server sends back to the client): la réponse
* «path operation»: «opération de chemin»
* «path operations» (plural): «opérations de chemin»
* «path operation function»: «fonction de chemin»
* «path operation decorator»: «décorateur d'opération de chemin»
- the request body: le corps de la requête
- the response body: le corps de la réponse
* «path parameter»: «paramètre de chemin»
* «query parameter»: «paramètre de requête»
- path operation: chemin d'accès
- path operations (plural): chemins d'accès
- path operation function: fonction de chemin d'accès
- path operation decorator: décorateur de chemin d'accès
* «the `Request`»: «`Request`» (keep as code identifier)
* «the `Response`»: «`Response`» (keep as code identifier)
- path parameter: paramètre de chemin
- query parameter: paramètre de requête
* «deployment»: «déploiement»
* «to upgrade»: «mettre à niveau»
- the `Request`: `Request` (keep as code identifier)
- the `Response`: `Response` (keep as code identifier)
* «deprecated»: «déprécié»
* «to deprecate»: «déprécier»
- deployment: déploiement
- to upgrade: mettre à niveau
* «cheat sheet»: «aide-mémoire»
* «plug-in»: «plug-in»
- deprecated: déprécié
- to deprecate: déprécier
- cheat sheet: aide-mémoire
- plug-in: plug-in

View File

@@ -1,41 +1,41 @@
# 追加のステータスコード
# 追加のステータスコード { #additional-status-codes }
デフォルトでは、 **FastAPI**`JSONResponse` を使ってレスポンスを返します。その `JSONResponse` の中には、 *path operation* が返した内容が入ります。
デフォルトでは、 **FastAPI**`JSONResponse` を使ってレスポンスを返し、*path operation* から返した内容をその `JSONResponse` の中に入れます。
それは、デフォルトのステータスコード*path operation*セットしたものを利用します。
デフォルトのステータスコード、または *path operation*設定したステータスコードが使用されます。
## 追加のステータスコード
## 追加のステータスコード { #additional-status-codes_1 }
メインのステータスコードとは別に、他のステータスコードを返したい場合は、`Response` (`JSONResponse` など) に追加のステータスコードを設定して直接返します。
メインのステータスコードとは別に追加のステータスコードを返したい場合は、`JSONResponse` のような `Response` を直接返し、追加のステータスコードを直接設定できます。
えば、itemを更新、成功した場合は200 "OK"のHTTPステータスコードを返す *path operation* を作りたいとします。
たとえば、item を更新でき、成功時に HTTP ステータスコード 200 "OK" を返す *path operation* を作りたいとします。
しかし、新しいitemも許可したいです。itemが存在しない場合は、それらを作成して201 "Created"を返します。
しかし、新しい item も受け付けたいとします。そして、item が以前存在しなかった場合には作成し、HTTP ステータスコード 201Createdを返します。
これを達成するには、 `JSONResponse` をインポートし、 `status_code` を設定して直接内容を返します。
これを実現するには、`JSONResponse` をインポートし、望む `status_code` を設定して、そこで内容を直接返します。
{* ../../docs_src/additional_status_codes/tutorial001.py hl[4,25] *}
{* ../../docs_src/additional_status_codes/tutorial001_an_py310.py hl[4,25] *}
/// warning | 注意
の例のように `Response`明示的に返す場合、それは直接返されます。
上の例のように `Response`直接返すと、それはそのまま返されます。
モデルなどシリアライズされません。
モデルなどによってシリアライズされません。
必要なデータが含まれていることや、値が有効なJSONであること (`JSONResponse` を使う場合) を確認してください。
必要なデータが含まれていること、そして(`JSONResponse` を使用している場合)値が有効な JSON であることを確認してください。
///
/// note | 技術詳細
`from starlette.responses import JSONResponse`利用することもできます。
`from starlette.responses import JSONResponse`使うこともできます。
**FastAPI** `fastapi.responses` と同じ `starlette.responses`、開発者の利便性のために提供しています。しかし有効なレスポンスほとんどStarletteからています。 `status` についても同です。
**FastAPI**開発者の利便性のために、`fastapi.responses` と同じ `starlette.responses` を提供しています。しかし、利用可能なレスポンスほとんどStarlette から直接提供されています。`status` も同です。
///
## OpenAPIAPIドキュメント
## OpenAPIAPI ドキュメント { #openapi-and-api-docs }
ステータスコードとレスポンスを直接返す場合、それらはOpenAPIスキーマ (APIドキュメント) には含まれません。なぜなら、FastAPIは何が返されるのか事前に知ることができないからです。
追加のステータスコードとレスポンスを直接返す場合、それらは OpenAPI スキーマAPI ドキュメントには含まれません。FastAPI には、事前に何が返されるかを知る方法がないからです。
しかし、 [Additional Responses](additional-responses.md){.internal-link target=_blank} を使ってコードの中にドキュメントを書くことができます。
しかし、[Additional Responses](additional-responses.md){.internal-link target=_blank} を使ってコードにドキュメントできます。

View File

@@ -1,34 +1,40 @@
# カスタムレスポンス - HTML、ストリーム、ファイル、その他のレスポンス
# カスタムレスポンス - HTML、ストリーム、ファイル、その他のレスポンス { #custom-response-html-stream-file-others }
デフォルトでは、**FastAPI** は `JSONResponse` を使ってレスポンスを返します。
[レスポンスを直接返す](response-directly.md){.internal-link target=_blank}で見たように、 `Response` を直接返すことでこの挙動をオーバーライドできます。
しかし、`Response` を直接返すと、データは自動的に変換されず、ドキュメントも自動生成されません (例えば、生成されるOpenAPIの一部としてHTTPヘッダー `Content-Type` に特定の「メディアタイプ」を含めるなど)
しかし、`Response` を直接返すと(または `JSONResponse` のような任意のサブクラスを返すと)、データは自動的に変換されず(`response_model` を宣言していても)、ドキュメントも自動生成されません例えば、生成されるOpenAPIの一部としてHTTPヘッダー `Content-Type` に特定の「メディアタイプ」を含めるなど
しかし、*path operationデコレータ* に、使いたい `Response` を宣言することもできます。
`response_class` パラメータを使用して、*path operation デコレータ* で使用したい `Response`(任意の `Response` サブクラス)を宣言することもできます。
*path operation関数* から返されるコンテンツは、その `Response` に含まれます。
*path operation 関数* から返されるコンテンツは、その `Response` に含まれます。
そしてもし、`Response` が、`JSONResponse``UJSONResponse` の場合のようにJSONメディアタイプ (`application/json`) ならば、データ*path operationデコレータ* に宣言したPydantic `response_model` により自動的に変換 (もしくはフィルタ) されます。
そしてその `Response` が、`JSONResponse``UJSONResponse` の場合のようにJSONメディアタイプ`application/json`)なら、関数の返り値*path operationデコレータ* に宣言した任意のPydantic `response_model` により自動的に変換(およびフィルタされます。
/// note | 備考
メディアタイプを指定せずにレスポンスクラスを利用すると、FastAPIは何もコンテンツがないことを期待します。そのため、生成されるOpenAPIドキュメントにレスポンスフォーマットが記載されません。
メディアタイプを指定せずにレスポンスクラスを利用すると、FastAPIはレスポンスにコンテンツがないことを期待します。そのため、生成されるOpenAPIドキュメントにレスポンスフォーマットが記載されません。
///
## `ORJSONResponse` を使う
## `ORJSONResponse` を使う { #use-orjsonresponse }
例えば、パフォーマンスを出したい場合は、<a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>をインストールし、`ORJSONResponse`をレスポンスとしてセットすることができます。
例えば、パフォーマンスを絞り出したい場合は、<a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>をインストールし、レスポンスとして `ORJSONResponse` をセットできます。
使いたい `Response` クラス (サブクラス) をインポートし、 *path operationデコレータ* に宣言します。
使いたい `Response` クラスサブクラスをインポートし、*path operationデコレータ* に宣言します。
{* ../../docs_src/custom_response/tutorial001b.py hl[2,7] *}
大きなレスポンスの場合、`Response` を直接返すほうが、辞書を返すよりもはるかに高速です。
これは、デフォルトではFastAPIがチュートリアルで説明した同じ[JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank}を使って、内部の各アイテムを検査し、JSONとしてシリアライズ可能であることを確認するためです。これにより、例えばデータベースモデルのような**任意のオブジェクト**を返せます。
しかし、返そうとしているコンテンツが **JSONでシリアライズ可能**であることが確実なら、それを直接レスポンスクラスに渡して、FastAPIがレスポンスクラスへ渡す前に返却コンテンツを `jsonable_encoder` に通すことで発生する追加のオーバーヘッドを回避できます。
{* ../../docs_src/custom_response/tutorial001b_py39.py hl[2,7] *}
/// info | 情報
パラメータ `response_class` は、レスポンスの「メディアタイプ」を定義するために利用することもできます。
パラメータ `response_class` は、レスポンスの「メディアタイプ」を定義するために利用されます。
この場合、HTTPヘッダー `Content-Type` には `application/json` がセットされます。
@@ -38,70 +44,70 @@
/// tip | 豆知識
`ORJSONResponse`、現在はFastAPIのみ利用可能で、Starletteでは利用できません。
`ORJSONResponse` はFastAPIのみ利用可能で、Starletteでは利用できません。
///
## HTMLレスポンス
## HTMLレスポンス { #html-response }
**FastAPI** からHTMLを直接返す場合は、`HTMLResponse` を使います。
* `HTMLResponse` をインポートする。
* *path operation* のパラメータ `content_type``HTMLResponse` を渡す。
* *path operation デコレータ* のパラメータ `response_class``HTMLResponse` を渡す。
{* ../../docs_src/custom_response/tutorial002.py hl[2,7] *}
{* ../../docs_src/custom_response/tutorial002_py39.py hl[2,7] *}
/// info | 情報
パラメータ `response_class` は、レスポンスの「メディアタイプ」を定義するために利用されます。
パラメータ `response_class` は、レスポンスの「メディアタイプ」を定義するために利用されます。
この場合、HTTPヘッダー `Content-Type` には `text/html` がセットされます。
そして、OpenAPIにはそのようにドキュメントされます。
そして、OpenAPIにはそのようにドキュメントされます。
///
### `Response` を返す
### `Response` を返す { #return-a-response }
[レスポンスを直接返す](response-directly.md){.internal-link target=_blank}で見たように、レスポンスを直接返すことで、*path operation* の中でレスポンスをオーバーライドできます。
[レスポンスを直接返す](response-directly.md){.internal-link target=_blank}で見たように、レスポンスを返すことで、*path operation* の中でレスポンスを直接オーバーライドすることもできます。
上記と同じ例において、 `HTMLResponse` を返すと、このようになります:
{* ../../docs_src/custom_response/tutorial003.py hl[2,7,19] *}
{* ../../docs_src/custom_response/tutorial003_py39.py hl[2,7,19] *}
/// warning | 注意
*path operation関数* から直接返される `Response` は、OpenAPIにドキュメントされず (例えば、 `Content-Type` がドキュメントされない) 、自動的な対話的ドキュメントからも閲覧できません。
*path operation関数* から直接返される `Response` は、OpenAPIにドキュメントされず例えば、`Content-Type` がドキュメントされない、自動的な対話的ドキュメントでも表示されません。
///
/// info | 情報
もちろん、実際の `Content-Type` ヘッダーやステータスコードなどは、返された `Response` オブジェクトに由来しています。
もちろん、実際の `Content-Type` ヘッダーやステータスコードなどは、返された `Response` オブジェクトに由来します。
///
### OpenAPIドキュメントと `Response` のオーバーライド
### OpenAPIドキュメントと `Response` のオーバーライド { #document-in-openapi-and-override-response }
関数の中でレスポンスをオーバーライドしつつも、OpenAPI に「メディアタイプ」をドキュメント化したいなら、 `response_class` パラメータを使い、 `Response` オブジェクトを返します。
関数の中でレスポンスをオーバーライドしつつも、OpenAPI に「メディアタイプ」をドキュメント化したいなら、`response_class` パラメータを使用し、かつ `Response` オブジェクトを返します。
`response_class` はOpenAPIの *path operation* ドキュメントにのみ使用されますが、 `Response` はそのまま使用されます。
`response_class` はOpenAPIの*path operation*のドキュメント化のためにのみ使用され`Response` はそのまま使用されます。
#### `HTMLResponse` を直接返す
#### `HTMLResponse` を直接返す { #return-an-htmlresponse-directly }
例えば、このようになります:
{* ../../docs_src/custom_response/tutorial004.py hl[7,21,23] *}
{* ../../docs_src/custom_response/tutorial004_py39.py hl[7,21,23] *}
この例では、関数 `generate_html_response()` は、`str` のHTMLを返すのではなく `Response` を生成して返しています。
この例では、関数 `generate_html_response()` は、`str` のHTMLを返すのではなく`Response` を生成して返しています。
`generate_html_response()` を呼び出した結果を返すことにより、**FastAPI** の振る舞いを上書きする `Response` が既に返されています。
`generate_html_response()` を呼び出した結果を返すことにより、デフォルトの **FastAPI**挙動をオーバーライドする `Response` をすでに返しています。
しかし、一方では `response_class``HTMLResponse` を渡しているため、 **FastAPI** はOpenAPI対話的ドキュメントでHTMLとして `text/html` でドキュメント化する方法を知っています
しかし、`response_class` `HTMLResponse` を渡しているため、**FastAPI** はOpenAPI対話的ドキュメントで`text/html` のHTMLとしてどのようにドキュメント化すればよいかを理解できます:
<img src="/img/tutorial/custom-response/image01.png">
## 利用可能なレスポンス
## 利用可能なレスポンス { #available-responses }
以下が利用可能なレスポンスの一部です。
@@ -111,11 +117,11 @@
`from starlette.responses import HTMLResponse` も利用できます。
**FastAPI** は開発者の利便性のために `fastapi.responses` として `starlette.responses` と同じものを提供しています。しかし、利用可能なレスポンスのほとんどはStarletteから直接提供されます。
**FastAPI** は開発者の利便性のために`starlette.responses` と同じものを `fastapi.responses` として提供しています。しかし、利用可能なレスポンスのほとんどはStarletteから直接提供されます。
///
### `Response`
### `Response` { #response }
メインの `Response` クラスで、他の全てのレスポンスはこれを継承しています。
@@ -128,41 +134,53 @@
* `headers` - 文字列の `dict`
* `media_type` - メディアタイプを示す `str` 。例えば `"text/html"`
FastAPI (実際にはStarlette) は自動的にContent-Lengthヘッダーを含みます。また、media_typeに基づいたContent-Typeヘッダーを含み、テキストタイプのためにcharsetを追加します。
FastAPI実際にはStarletteは自動的にContent-Lengthヘッダーを含みます。また、`media_type` に基づいたContent-Typeヘッダーを含み、テキストタイプのためにcharsetを追加します。
{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
### `HTMLResponse`
### `HTMLResponse` { #htmlresponse }
上で読んだように、テキストやバイトを受け取り、HTMLレスポンスを返します。
### `PlainTextResponse`
### `PlainTextResponse` { #plaintextresponse }
テキストやバイトを受け取り、プレーンテキストのレスポンスを返します。
{* ../../docs_src/custom_response/tutorial005.py hl[2,7,9] *}
{* ../../docs_src/custom_response/tutorial005_py39.py hl[2,7,9] *}
### `JSONResponse`
### `JSONResponse` { #jsonresponse }
データを受け取り、 `application/json` としてエンコードされたレスポンスを返します。
データを受け取り、`application/json` としてエンコードされたレスポンスを返します。
上で読んだように、**FastAPI** のデフォルトのレスポンスとして利用されます。
### `ORJSONResponse`
### `ORJSONResponse` { #orjsonresponse }
上で読んだように、<a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>を使った、高速な代替のJSONレスポンスです。
### `UJSONResponse`
/// info | 情報
<a href="https://github.com/ultrajson/ultrajson" class="external-link" target="_blank">`ujson`</a>を使った、代替のJSONレスポンスです。
/// warning | 注意
`ujson` は、いくつかのエッジケースの取り扱いについて、Pythonにビルトインされた実装よりも作りこまれていません。
これは、例えば `pip install orjson``orjson` をインストールする必要があります。
///
{* ../../docs_src/custom_response/tutorial001.py hl[2,7] *}
### `UJSONResponse` { #ujsonresponse }
<a href="https://github.com/ultrajson/ultrajson" class="external-link" target="_blank">`ujson`</a>を使った、代替のJSONレスポンスです。
/// info | 情報
これは、例えば `pip install ujson``ujson` をインストールする必要があります。
///
/// warning | 注意
`ujson` は、いくつかのエッジケースの取り扱いについて、Pythonにビルトインされた実装ほど注意深くありません。
///
{* ../../docs_src/custom_response/tutorial001_py39.py hl[2,7] *}
/// tip | 豆知識
@@ -170,33 +188,61 @@ FastAPI (実際にはStarlette) は自動的にContent-Lengthヘッダーを含
///
### `RedirectResponse`
### `RedirectResponse` { #redirectresponse }
HTTPリダイレクトを返します。デフォルトでは307ステータスコード (Temporary Redirect) となります。
HTTPリダイレクトを返します。デフォルトでは307ステータスコードTemporary Redirectとなります。
{* ../../docs_src/custom_response/tutorial006.py hl[2,9] *}
`RedirectResponse` を直接返せます:
### `StreamingResponse`
{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *}
非同期なジェネレータか通常のジェネレータ・イテレータを受け取り、レスポンスボディをストリームします。
---
{* ../../docs_src/custom_response/tutorial007.py hl[2,14] *}
または、`response_class` パラメータで使用できます:
#### `StreamingResponse` をファイルライクなオブジェクトとともに使う
{* ../../docs_src/custom_response/tutorial006b_py39.py hl[2,7,9] *}
ファイルライクなオブジェクト (例えば、 `open()` で返されたオブジェクト) がある場合、 `StreamingResponse` に含めて返すことができます。
その場合、*path operation*関数からURLを直接返せます。
れにはクラウドストレージとの連携や映像処理など、多くのライブラリが含まれています。
の場合に使用される `status_code``RedirectResponse` のデフォルトである `307` になります。
{* ../../docs_src/custom_response/tutorial008.py hl[2,10:12,14] *}
---
また、`status_code` パラメータを `response_class` パラメータと組み合わせて使うこともできます:
{* ../../docs_src/custom_response/tutorial006c_py39.py hl[2,7,9] *}
### `StreamingResponse` { #streamingresponse }
非同期ジェネレータ、または通常のジェネレータ/イテレータを受け取り、レスポンスボディをストリームします。
{* ../../docs_src/custom_response/tutorial007_py39.py hl[2,14] *}
#### ファイルライクオブジェクトで `StreamingResponse` を使う { #using-streamingresponse-with-file-like-objects }
<a href="https://docs.python.org/3/glossary.html#term-file-like-object" class="external-link" target="_blank">file-like</a> オブジェクト(例: `open()` で返されるオブジェクトがある場合、そのfile-likeオブジェクトを反復処理するジェネレータ関数を作れます。
そうすれば、最初にすべてをメモリへ読み込む必要はなく、そのジェネレータ関数を `StreamingResponse` に渡して返せます。
これにはクラウドストレージとの連携、映像処理など、多くのライブラリが含まれます。
{* ../../docs_src/custom_response/tutorial008_py39.py hl[2,10:12,14] *}
1. これはジェネレータ関数です。内部に `yield` 文を含むため「ジェネレータ関数」です。
2. `with` ブロックを使うことで、ジェネレータ関数が終わった後つまりレスポンスの送信が完了した後にfile-likeオブジェクトが確実にクローズされるようにします。
3. この `yield from` は、`file_like` という名前のものを反復処理するように関数へ指示します。そして反復された各パートについて、そのパートをこのジェネレータ関数(`iterfile`)から来たものとして `yield` します。
つまり、内部的に「生成」の作業を別のものへ移譲するジェネレータ関数です。
このようにすることで `with` ブロックに入れられ、完了後にfile-likeオブジェクトが確実にクローズされます。
/// tip | 豆知識
ここでは `async` `await` をサポートしていない標準の `open()` を使っているので、通常の `def` でpath operationを宣言していることに注意してください。
ここでは `async` `await` をサポートしていない標準の `open()` を使っているため、通常の `def` でpath operationを宣言しているに注意してください。
///
### `FileResponse`
### `FileResponse` { #fileresponse }
レスポンスとしてファイルを非同期的にストリームします。
@@ -204,29 +250,63 @@ HTTPリダイレクトを返します。デフォルトでは307ステータス
* `path` - ストリームするファイルのファイルパス。
* `headers` - 含めたい任意のカスタムヘッダーの辞書。
* `media_type` - メディアタイプを示す文字列。セットされなかった場合、ファイル名やパスからメディアタイプが推されます。
* `filename` - セットされた場合、レスポンスの `Content-Disposition` に含まれます。
* `media_type` - メディアタイプを示す文字列。未設定の場合、ファイル名やパスからメディアタイプが推されます。
* `filename` - 設定した場合、レスポンスの `Content-Disposition` に含まれます。
ファイルレスポンスには、適切な `Content-Length``Last-Modified``ETag` ヘッダーが含まれます。
ファイルレスポンスには、適切な `Content-Length``Last-Modified``ETag` ヘッダーが含まれます。
{* ../../docs_src/custom_response/tutorial009.py hl[2,10] *}
{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *}
## デフォルトレスポンスクラス
`response_class` パラメータを使うこともできます:
**FastAPI** クラスのインスタンスか `APIRouter` を生成するときに、デフォルトのレスポンスクラスを指定できます。
{* ../../docs_src/custom_response/tutorial009b_py39.py hl[2,8,10] *}
定義するためのパラメータは、 `default_response_class`す。
この場合、*path operation*関数からファイルパスを直接返せます。
以下の例では、 **FastAPI** は、全ての *path operation*`JSONResponse` の代わりに `ORJSONResponse` をデフォルトとして利用します。
## カスタムレスポンスクラス { #custom-response-class }
{* ../../docs_src/custom_response/tutorial010.py hl[2,4] *}
`Response` を継承した独自のカスタムレスポンスクラスを作成して利用できます。
例えば、<a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>を使いたいが、同梱の `ORJSONResponse` クラスで使われていないカスタム設定も使いたいとします。
例えば、インデントされ整形されたJSONを返したいので、orjsonオプション `orjson.OPT_INDENT_2` を使いたいとします。
`CustomORJSONResponse` を作れます。主に必要なのは、コンテンツを `bytes` として返す `Response.render(content)` メソッドを作ることです:
{* ../../docs_src/custom_response/tutorial009c_py39.py hl[9:14,17] *}
これまでは次のように返していたものが:
```json
{"message": "Hello World"}
```
...このレスポンスでは次のように返されます:
```json
{
"message": "Hello World"
}
```
もちろん、JSONの整形よりも、これを活用するもっと良い方法が見つかるはずです。 😉
## デフォルトレスポンスクラス { #default-response-class }
**FastAPI** クラスのインスタンス、または `APIRouter` を作成する際に、デフォルトで使用するレスポンスクラスを指定できます。
これを定義するパラメータは `default_response_class` です。
以下の例では、**FastAPI** はすべての*path operation*で、`JSONResponse` の代わりに `ORJSONResponse` をデフォルトとして使います。
{* ../../docs_src/custom_response/tutorial010_py39.py hl[2,4] *}
/// tip | 豆知識
前に見たように、 *path operation* の中`response_class` をオーバーライドできます。
これまでと同様に、*path operation*`response_class` をオーバーライドできます。
///
## その他のドキュメント
## その他のドキュメント { #additional-documentation }
また、OpenAPIでは `responses` を使ってメディアタイプやその他の詳細を宣言することもできます: [Additional Responses in OpenAPI](additional-responses.md){.internal-link target=_blank}
OpenAPIでは `responses` を使ってメディアタイプやその他の詳細を宣言することもできます: [Additional Responses in OpenAPI](additional-responses.md){.internal-link target=_blank}

View File

@@ -1,27 +1,21 @@
# 高度なユーザーガイド
# 高度なユーザーガイド { #advanced-user-guide }
## さらなる機能
## さらなる機能 { #additional-features }
[チュートリアル - ユーザーガイド](../tutorial/index.md){.internal-link target=_blank}により、**FastAPI**の主要な機能は十分に理解できたことでしょう
メインの[チュートリアル - ユーザーガイド](../tutorial/index.md){.internal-link target=_blank}だけで、**FastAPI**の主要な機能を一通り把握するには十分なはずです
以降のセクションでは、チュートリアルでは説明しきれなかったオプション設定、および機能について説明します。
以降のセクションでは、その他のオプション設定、追加機能を見ていきます。
/// tip | 豆知識
以降のセクションは、 **必ずしも"応用編"ではありません**
以降のセクションは、**必ずしも「高度」ではありません**。
ユースケースによっては、その中から解決策を見つけられるかもしれません
また、あなたのユースケースに対する解決策が、その中のどれかにある可能性もあります
///
## 先にチュートリアルを読む
## 先にチュートリアルを読む { #read-the-tutorial-first }
[チュートリアル - ユーザーガイド](../tutorial/index.md){.internal-link target=_blank}知識があれば、**FastAPI**の主要な機能を利用することができます。
メインの[チュートリアル - ユーザーガイド](../tutorial/index.md){.internal-link target=_blank}で得た知識があれば、**FastAPI**の機能の多くは引き続き利用できます。
以降のセクションは、すでにチュートリアルを読んで、その主要なアイデアを理解できていることを前提としています。
## テスト駆動開発のコース
このセクションの内容を補完するために脱初心者用コースを受けたい場合は、**TestDriven.io**による、<a href="https://testdriven.io/courses/tdd-fastapi/" class="external-link" target="_blank">Test-Driven Development with FastAPI and Docker</a>を確認するのがよいかもしれません。
現在、このコースで得られた利益の10%が**FastAPI**の開発のために寄付されています。🎉 😄
また、以降のセクションは、すでにそれを読んでいて、主要な考え方を理解ていることを前提としています。

View File

@@ -1,30 +1,30 @@
# Path Operationの高度な設定
# Path Operationの高度な設定 { #path-operation-advanced-configuration }
## OpenAPI operationId
## OpenAPI operationId { #openapi-operationid }
/// warning | 注意
あなたがOpenAPIの「エキスパート」でなければ、これは必要ないかもしれません。
OpenAPIの「エキスパート」でなければ、これはおそらく必要ありません。
///
*path operation*`operation_id` パラメータを利用することで、OpenAPIの `operationId` を設定できます。
`operation_id`各オペレーションで一意にする必要があります。
各オペレーションで一意になるようにする必要があります。
{* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
### *path operation関数* の名前をoperationIdとして使用する
### *path operation関数* の名前をoperationIdとして使用する { #using-the-path-operation-function-name-as-the-operationid }
APIの関数名を `operationId` として利用したい場合、すべてのAPI関数をイテレーションし、各 *path operation*`operationId``APIRoute.name` で上書きすれば可能です。
APIの関数名を `operationId` として利用したい場合、すべてのAPI関数をイテレーションし、各 *path operation*`operation_id``APIRoute.name` で上書きすれば可能です。
そうする場合は、すべての *path operation* を追加した後に行う必要があります。
すべての *path operation* を追加した後に行うべきです。
{* ../../docs_src/path_operation_advanced_configuration/tutorial002.py hl[2,12:21,24] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *}
/// tip | 豆知識
`app.openapi()` を手動でコールする場合、その前に`operationId`を更新する必要があります。
`app.openapi()` を手動で呼び出す場合、その前に `operationId` を更新するべきです。
///
@@ -32,22 +32,141 @@ APIの関数名を `operationId` として利用したい場合、すべてのAP
この方法をとる場合、各 *path operation関数* が一意な名前である必要があります。
それらが異なるモジュール (Pythonファイル) にあるとしてもです。
異なるモジュールPythonファイルにある場合でも同様です。
///
## OpenAPIから除外する
## OpenAPIから除外する { #exclude-from-openapi }
生成されるOpenAPIスキーマ (つまり、自動ドキュメント生成の仕組み) から *path operation* を除外するには、 `include_in_schema` パラメータを `False` にします。
生成されるOpenAPIスキーマつまり、自動ドキュメント生成の仕組みから *path operation* を除外するには、`include_in_schema` パラメータを使用して `False`設定します。
{* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *}
## docstringによる説明の高度な設定
## docstringによる説明の高度な設定 { #advanced-description-from-docstring }
*path operation関数* のdocstringからOpenAPIに使用する行を制限することができます。
*path operation関数* のdocstringからOpenAPIに使用する行を制限できます。
`\f` (「書式送り (Form Feed)」のエスケープ文字) を付与することで、**FastAPI** はOpenAPIに使用される出力をその箇所までに制限します。
`\f`(エスケープされた「書式送りform feed)」文字)を追加すると、**FastAPI** はその地点でOpenAPIに使用される出力を切り詰めます。
ドキュメントには表示されませんが、他のツール (例えばSphinx) では残りの部分を利用できるでしょう
ドキュメントには表示されませんが、他のツールSphinxなど)は残りの部分を利用できます
{* ../../docs_src/path_operation_advanced_configuration/tutorial004.py hl[19:29] *}
{* ../../docs_src/path_operation_advanced_configuration/tutorial004_py310.py hl[17:27] *}
## 追加レスポンス { #additional-responses }
*path operation* に対して `response_model``status_code` を宣言する方法はすでに見たことがあるでしょう。
それにより、*path operation* のメインのレスポンスに関するメタデータが定義されます。
追加のレスポンスについても、モデルやステータスコードなどとともに宣言できます。
これについてはドキュメントに章全体があります。 [OpenAPIの追加レスポンス](additional-responses.md){.internal-link target=_blank} で読めます。
## OpenAPI Extra { #openapi-extra }
アプリケーションで *path operation* を宣言すると、**FastAPI** はOpenAPIスキーマに含めるために、その *path operation* に関連するメタデータを自動的に生成します。
/// note | 技術詳細
OpenAPI仕様では <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object" class="external-link" target="_blank">Operation Object</a> と呼ばれています。
///
これには *path operation* に関するすべての情報が含まれ、自動ドキュメントを生成するために使われます。
`tags``parameters``requestBody``responses` などが含まれます。
この *path operation* 固有のOpenAPIスキーマは通常 **FastAPI** により自動生成されますが、拡張することもできます。
/// tip | 豆知識
これは低レベルな拡張ポイントです。
追加レスポンスを宣言するだけなら、より便利な方法として [OpenAPIの追加レスポンス](additional-responses.md){.internal-link target=_blank} を使うことができます。
///
`openapi_extra` パラメータを使って、*path operation* のOpenAPIスキーマを拡張できます。
### OpenAPI Extensions { #openapi-extensions }
この `openapi_extra` は、例えば [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] *}
自動APIドキュメントを開くと、その拡張は特定の *path operation* の下部に表示されます。
<img src="/img/tutorial/path-operation-advanced-configuration/image01.png">
そしてAPIの `/openapi.json` にある生成されたOpenAPIを見ると、その拡張も特定の *path operation* の一部として確認できます。
```JSON hl_lines="22"
{
"openapi": "3.1.0",
"info": {
"title": "FastAPI",
"version": "0.1.0"
},
"paths": {
"/items/": {
"get": {
"summary": "Read Items",
"operationId": "read_items_items__get",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {}
}
}
}
},
"x-aperture-labs-portal": "blue"
}
}
}
}
```
### カスタムOpenAPI *path operation* スキーマ { #custom-openapi-path-operation-schema }
`openapi_extra` 内の辞書は、*path operation* 用に自動生成されたOpenAPIスキーマと深くマージされます。
そのため、自動生成されたスキーマに追加データを加えることができます。
例えば、Pydanticを使ったFastAPIの自動機能を使わずに独自のコードでリクエストを読み取り・検証することを選べますが、それでもOpenAPIスキーマでリクエストを定義したい場合があります。
それは `openapi_extra` で行えます。
{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
この例では、Pydanticモデルを一切宣言していません。実際、リクエストボディはJSONとして <abbr title="converted from some plain format, like bytes, into Python objects bytesなどのプレーンな形式からPythonオブジェクトに変換すること">parsed</abbr> されず、直接 `bytes` として読み取られます。そして `magic_data_reader()` 関数が、何らかの方法でそれをパースする責務を担います。
それでも、リクエストボディに期待されるスキーマを宣言できます。
### カスタムOpenAPI content type { #custom-openapi-content-type }
同じトリックを使って、PydanticモデルでJSON Schemaを定義し、それを *path operation* 用のカスタムOpenAPIスキーマセクションに含めることができます。
また、リクエスト内のデータ型がJSONでない場合でもこれを行えます。
例えばこのアプリケーションでは、PydanticモデルからJSON Schemaを抽出するFastAPIの統合機能や、JSONの自動バリデーションを使っていません。実際、リクエストのcontent typeをJSONではなくYAMLとして宣言しています。
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
それでも、デフォルトの統合機能を使っていないにもかかわらず、YAMLで受け取りたいデータのために、Pydanticモデルを使って手動でJSON Schemaを生成しています。
そしてリクエストを直接使い、ボディを `bytes` として抽出します。これは、FastAPIがリクエストペイロードをJSONとしてパースしようとすらしないことを意味します。
その後、コード内でそのYAMLコンテンツを直接パースし、さらに同じPydanticモデルを使ってYAMLコンテンツを検証しています。
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
/// tip | 豆知識
ここでは同じPydanticモデルを再利用しています。
ただし同様に、別の方法で検証することもできます。
///

View File

@@ -1,4 +1,4 @@
# レスポンスを直接返す
# レスポンスを直接返す { #return-a-response-directly }
**FastAPI***path operation* では、通常は任意のデータを返すことができます: 例えば、 `dict``list`、Pydanticモデル、データベースモデルなどです。
@@ -10,7 +10,7 @@
これは例えば、カスタムヘッダーやcookieを返すときに便利です。
## `Response` を返す
## `Response` を返す { #return-a-response }
実際は、`Response` やそのサブクラスを返すことができます。
@@ -26,7 +26,7 @@
これは多くの柔軟性を提供します。任意のデータ型を返したり、任意のデータ宣言やバリデーションをオーバーライドできます。
## `jsonable_encoder` を `Response` の中で使う
## `jsonable_encoder` を `Response` の中で使う { #using-the-jsonable-encoder-in-a-response }
**FastAPI** はあなたが返す `Response` に対して何も変更を加えないので、コンテンツが準備できていることを保証しなければなりません。
@@ -34,7 +34,7 @@
このようなケースでは、レスポンスにデータを含める前に `jsonable_encoder` を使ってデータを変換できます。
{* ../../docs_src/response_directly/tutorial001.py hl[6:7,21:22] *}
{* ../../docs_src/response_directly/tutorial001_py310.py hl[5:6,20:21] *}
/// note | 技術詳細
@@ -44,7 +44,7 @@
///
## カスタム `Response` を返す
## カスタム `Response` を返す { #returning-a-custom-response }
上記の例では必要な部分を全て示していますが、あまり便利ではありません。`item` を直接返すことができるし、**FastAPI** はそれを `dict` に変換して `JSONResponse` に含めてくれるなど。すべて、デフォルトの動作です。
@@ -54,9 +54,9 @@
XMLを文字列にし、`Response` に含め、それを返します。
{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
## 備考
## 備考 { #notes }
`Response` を直接返す場合、バリデーションや、変換 (シリアライズ) や、自動ドキュメントは行われません。

View File

@@ -1,10 +1,10 @@
# WebSocket
# WebSockets { #websockets }
**FastAPI**で<a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API" class="external-link" target="_blank">WebSocket</a>が使用できます。
**FastAPI**で<a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API" class="external-link" target="_blank">WebSockets</a>が使用できます。
## `WebSockets`のインストール
## `websockets`のインストール { #install-websockets }
まず `WebSockets`インストールが必要です
[仮想環境](../virtual-environments.md){.internal-link target=_blank}を作成し、それを有効化してから、「WebSocket」プロトコルを簡単に使えるようにするPythonライブラリの`websockets`インストールしてください
<div class="termy">
@@ -16,13 +16,13 @@ $ pip install websockets
</div>
## WebSocket クライアント
## WebSockets クライアント { #websockets-client }
### 本番環境
### 本番環境 { #in-production }
本番環境では、React、Vue.js、Angularなどの最新のフレームワークで作成されたフロントエンドを使用しているでしょう。
そして、バックエンドとWebSocketを使用して通信するために、おそらくフロントエンドのユーティリティを使用することになるでしょう。
そして、バックエンドとWebSocketsを使用して通信するために、おそらくフロントエンドのユーティリティを使用することになるでしょう。
または、ネイティブコードでWebSocketバックエンドと直接通信するネイティブモバイルアプリケーションがあるかもしれません。
@@ -30,21 +30,21 @@ $ pip install websockets
---
ただし、この例では非常にシンプルなHTML文書といくつかのJavaScriptを、すべてソースコードの中に入れて使用することにします。
ただし、この例では非常にシンプルなHTML文書といくつかのJavaScriptを、すべて長い文字列の中に入れて使用することにします。
もちろん、これは最適な方法ではありませんし、本番環境で使うことはないでしょう。
本番環境では、上記の方法のいずれかの選択肢を採用することになるでしょう。
しかし、これはWebSocketのサーバーサイドに焦点を当て、実用的な例を示す最も簡単な方法です。
しかし、これはWebSocketsのサーバーサイドに焦点を当て、動作する例を示す最も簡単な方法です。
{* ../../docs_src/websockets/tutorial001.py hl[2,6:38,41:43] *}
{* ../../docs_src/websockets/tutorial001_py39.py hl[2,6:38,41:43] *}
## `websocket` を作成する
## `websocket` を作成する { #create-a-websocket }
**FastAPI** アプリケーションで、`websocket` を作成します。
{* ../../docs_src/websockets/tutorial001.py hl[1,46:47] *}
{* ../../docs_src/websockets/tutorial001_py39.py hl[1,46:47] *}
/// note | 技術詳細
@@ -54,22 +54,22 @@ $ pip install websockets
///
## メッセージの送受信
## メッセージを待機して送信する { #await-for-messages-and-send-messages }
WebSocketルートでは、 `await` を使ってメッセージの送受信ができます。
WebSocketルートでは、メッセージを待機して送信するために `await` を使できます。
{* ../../docs_src/websockets/tutorial001.py hl[48:52] *}
{* ../../docs_src/websockets/tutorial001_py39.py hl[48:52] *}
バイナリやテキストデータ、JSONデータを送受信できます。
## 試してみる
## 試してみる { #try-it }
ファイル名が `main.py` である場合、以下の方法でアプリケーションを実行します。
ファイル名が `main.py` である場合、以下でアプリケーションを実行します。
<div class="termy">
```console
$ uvicorn main:app --reload
$ fastapi dev main.py
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
@@ -86,7 +86,7 @@ $ uvicorn main:app --reload
<img src="/img/tutorial/websockets/image02.png">
そして、 WebSocketを使用した**FastAPI**アプリケーションが応答します。
そして、 WebSocketsを使用した**FastAPI**アプリケーションが応答します。
<img src="/img/tutorial/websockets/image03.png">
@@ -96,7 +96,7 @@ $ uvicorn main:app --reload
そして、これらの通信はすべて同じWebSocket接続を使用します。
## 依存関係
## `Depends` などの使用 { #using-depends-and-others }
WebSocketエンドポイントでは、`fastapi` から以下をインポートして使用できます。
@@ -107,28 +107,26 @@ WebSocketエンドポイントでは、`fastapi` から以下をインポート
* `Path`
* `Query`
これらは、他のFastAPI エンドポイント/*path operation* の場合と同じように機能します。
これらは、他のFastAPI エンドポイント/*path operations* の場合と同じように機能します。
{* ../../docs_src/websockets/tutorial002.py hl[58:65,68:83] *}
{* ../../docs_src/websockets/tutorial002_an_py310.py hl[68:69,82] *}
/// info | 情報
WebSocket`HTTPException` を発生させることはあまり意味がありません。したがって、WebSocketの接続を直接閉じる方がよいでしょう
これはWebSocketであるため、`HTTPException` を発生させることはあまり意味がありません。代わりに `WebSocketException` を発生させます
クロージングコードは、<a href="https://tools.ietf.org/html/rfc6455#section-7.4.1" class="external-link" target="_blank">仕様で定義された有効なコード</a>の中から使用することができます。
将来的には、どこからでも `raise` できる `WebSocketException` が用意され、専用の例外ハンドラを追加できるようになる予定です。これは、Starlette の <a href="https://github.com/encode/starlette/pull/527" class="external-link" target="_blank">PR #527</a> に依存するものです。
///
### 依存関係を用いてWebSocketsを試してみる
### 依存関係を用いてWebSocketsを試してみる { #try-the-websockets-with-dependencies }
ファイル名が `main.py` である場合、以下の方法でアプリケーションを実行します。
ファイル名が `main.py` である場合、以下でアプリケーションを実行します。
<div class="termy">
```console
$ uvicorn main:app --reload
$ fastapi dev main.py
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
@@ -137,14 +135,14 @@ $ uvicorn main:app --reload
ブラウザで <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a> を開きます。
クライアントが設定できる項目は以下の通りです。
そこで、以下を設定できます。
* パスで使用される「Item ID」
* クエリパラメータとして使用される「Token」
/// tip | 豆知識
クエリ `token` は依存パッケージによって処理されることに注意してください。
クエリ `token` は依存関係によって処理されることに注意してください。
///
@@ -152,11 +150,11 @@ $ uvicorn main:app --reload
<img src="/img/tutorial/websockets/image05.png">
## 切断や複数クライアントへの対応
## 切断や複数クライアントの処理 { #handling-disconnections-and-multiple-clients }
WebSocket接続が閉じられると、 `await websocket.receive_text()` は例外 `WebSocketDisconnect` を発生させ、この例のようにキャッチして処理することができます。
{* ../../docs_src/websockets/tutorial003.py hl[81:83] *}
{* ../../docs_src/websockets/tutorial003_py39.py hl[79:81] *}
試してみるには、
@@ -174,15 +172,15 @@ Client #1596980209979 left the chat
上記のアプリは、複数の WebSocket 接続に対してメッセージを処理し、ブロードキャストする方法を示すための最小限のシンプルな例です。
しかし、すべての接続がメモリ内の単一のリストで処理されるため、プロセスの実行中にのみ機能し、単一のプロセスでのみ機能することに注意してください。
しかし、すべてがメモリ内の単一のリストで処理されるため、プロセスの実行中にのみ機能し、単一のプロセスでのみ機能することに注意してください。
もしFastAPIと簡単に統合できて、RedisやPostgreSQLなどでサポートされている、より堅牢なものが必要なら、<a href="https://github.com/encode/broadcaster" class="external-link" target="_blank">encode/broadcaster</a> を確認してください。
FastAPIと簡単に統合できて、RedisやPostgreSQLなどでサポートされている、より堅牢なものが必要なら、<a href="https://github.com/encode/broadcaster" class="external-link" target="_blank">encode/broadcaster</a> を確認してください。
///
## その他のドキュメント
## 詳細情報 { #more-info }
オプションの詳細については、Starletteのドキュメントを確認してください。
* <a href="https://www.starlette.dev/websockets/" class="external-link" target="_blank"> `WebSocket` クラス</a>
* <a href="https://www.starlette.dev/endpoints/#websocketendpoint" class="external-link" target="_blank">クラスベースのWebSocket処理</a>
* <a href="https://www.starlette.dev/websockets/" class="external-link" target="_blank">`WebSocket` クラス</a>.
* <a href="https://www.starlette.dev/endpoints/#websocketendpoint" class="external-link" target="_blank">クラスベースのWebSocket処理</a>.

View File

@@ -1,34 +1,34 @@
# ベンチマーク
# ベンチマーク { #benchmarks }
TechEmpowerの独立したベンチマークでは、Uvicornの下で動作する**FastAPI**アプリケーションは、<a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">利用可能な最速のPythonフレームワークの1つ</a>であり、下回っているのはStarletteとUvicorn自体 (FastAPIによって内部で使用される) のみだと示されています。
TechEmpowerの独立したベンチマークでは、Uvicornの下で動作する**FastAPI**アプリケーションは、<a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">利用可能な最速のPythonフレームワークの1つ</a>であり、下回っているのはStarletteとUvicorn自体FastAPIによって内部で使用されるのみだと示されています。
ただし、ベンチマークを確認し、比較する際には下記の内容に気を付けてください。
## ベンチマークと速度
## ベンチマークと速度 { #benchmarks-and-speed }
ベンチマークを確認する時、異なるツール同等ものと比較するのが一般的です。
ベンチマークを確認する時、異なるタイプの複数のツール同等ものとして比較されているのを目にするのが一般的です。
具体的には、Uvicorn、Starlette、FastAPIを (他の多くのツールと) 比較しました
具体的には、Uvicorn、Starlette、FastAPIを他の多くのツールの中で)まとめて比較しているのを目にすることがあります
ツールで解決する問題がシンプルなほど、パフォーマンスが向上します。また、ほとんどのベンチマークは、ツールから提供される追加機能をテストしていません。
階層関係はこのようになります。
* **Uvicorn**: ASGIサーバー
* **Starlette**: (Uvicornを使用) WEBマイクロフレームワーク
* **FastAPI**: (Starletteを使用) データバリデーションなど、APIを構築する追加機能を備えたAPIマイクロフレームワーク
* **Starlette**: Uvicornを使用webマイクロフレームワーク
* **FastAPI**: Starletteを使用データバリデーションなど、APIを構築するためのいくつかの追加機能を備えたAPIマイクロフレームワーク
* **Uvicorn**:
* サーバー自体に余分なコードが少ないので、最高のパフォーマンスが得られます。
* Uvicornにアプリケーションを直接書くことはできません。つまり、あなたのコードに、Starlette (または** FastAPI **) が提供するコードを、多かれ少なかれ含める必要があります。そうすると、最終的なアプリケーションは、フレームワークを使用してアプリのコードとバグを最小限に抑えた場合と同じオーバーヘッドになります。
* もしUvicornを比較する場合は、Daphne、Hypercorn、uWSGIなどのアプリケーションサーバーと比較してください。
* サーバー自体以外に余分なコードがあまりないため、最高のパフォーマンスになります。
* Uvicornにアプリケーションを直接書くことはないでしょう。それは、あなたのコードに、Starletteまたは**FastAPI**が提供するコードを、少なくとも多かれ少なかれ含める必要があるということです。そして、もしそうした場合、最終的なアプリケーションは、フレームワークを使用してアプリのコードとバグを最小限に抑えた場合と同じオーバーヘッドになります。
* Uvicornを比較する場合は、Daphne、Hypercorn、uWSGIなどのアプリケーションサーバーと比較してください。
* **Starlette**:
* Uvicornに次ぐ性能を持つでしょう。実際、StarletteはUvicornを使用しています。だから、より多くのコードを実行する必要があり、Uvicornより「遅く」なってしまうだけなのです。
* しかし、パスベースのルーティングなどシンプルなWEBアプリケーションを構築する機能を提供します。
* もしStarletteを比較する場合は、Sanic、Flask、DjangoなどのWEBフレームワーク (もしくはマイクロフレームワーク) と比較してください。
* Uvicornに次ぐ性能になるでしょう。実際、Starletteは実行にUvicornを使用しています。そのため、おそらく、より多くのコードを実行しなければならない分だけ、Uvicornより「遅く」なるだけです。
* しかし、パスに基づくルーティングなどを使って、シンプルなwebアプリケーションを構築するためのツールを提供します。
* Starletteを比較する場合は、Sanic、Flask、Djangoなどのwebフレームワーク(またはマイクロフレームワークと比較してください。
* **FastAPI**:
* StarletteがUvicornを使っているのと同じ、**FastAPI**はStarletteを使っており、それより速くできません。
* FastAPIはStarletteの上にさらに多くの機能を提供します。データの検証やシリアライゼーションなど、APIを構築する際に常に必要な機能です。また、それを使用することで、自動ドキュメント化を無料で取得できます (ドキュメントは実行中のアプリケーションにオーバーヘッドを追加せず、起動時に生成されます)
* FastAPIを使用せず、直接Starlette (またはSanic, Flask, Responderなど) を使用した場合、データの検証とシリアライをすべて自分で実装する必要があります。そのため、最終的なアプリケーションはFastAPIを使用して構築した場合と同じオーバーヘッドが発生します。そして多くの場合、このデータ検証とシリアライは、アプリケーションのコードの中で最大の記述量になります。
* FastAPIを使用することで、開発時間、バグ、コード行数を節約でき、使用しない場合 (あなたが全ての機能を実装し直した場合) と同じかそれ以上のパフォーマンスを得られます。
* もしFastAPIを比較する場合は、Flask-apispec、NestJS、Moltenなどデータ検証や、シリアライズの機能を提供するWEBフレームワーク (や機能のセット) と比較してください。これらはデータの自動検証や、シリアライ、ドキュメント化が統合されたフレームワークです。
* StarletteがUvicornを使用しており、それより速くできないのと同じように、**FastAPI**はStarletteを使用しているため、それより速くできません。
* FastAPIはStarletteの上に、より多くの機能を提供します。データバリデーションやシリアライゼーションのように、APIを構築する際にほとんど常に必要な機能です。また、それを使用することで、自動ドキュメント化を無料で利用できます(自動ドキュメントは実行中のアプリケーションにオーバーヘッドを追加せず、起動時に生成されます
* FastAPIを使用せず、Starletteを直接(またはSanicFlaskResponderなど別のツールを)使用した場合、データバリデーションとシリアライゼーションをすべて自分で実装する必要があります。そのため、最終的なアプリケーションはFastAPIを使用して構築した場合と同じオーバーヘッドが発生します。そして多くの場合、このデータバリデーションとシリアライゼーションは、アプリケーションで書かれるコードの大部分になります。
* そのため、FastAPIを使用することで、開発時間、バグ、コード行数を節約でき、使用しない場合あなたがそれをすべて自分のコードで実装する必要があるため)と比べて、同じパフォーマンス(またはそれ以上)を得られる可能性があります。
* FastAPIを比較する場合は、Flask-apispec、NestJS、Moltenなどデータバリデーション、シリアライゼーション、ドキュメント化を提供するwebアプリケーションフレームワークまたはツール群と比較してください。自動データバリデーション、シリアライゼーション、ドキュメント化が統合されたフレームワークです。

View File

@@ -1,4 +1,4 @@
# デプロイメントのコンセプト
# デプロイメントのコンセプト { #deployments-concepts }
**FastAPI**を用いたアプリケーションをデプロイするとき、もしくはどのようなタイプのWeb APIであっても、おそらく気になるコンセプトがいくつかあります。
@@ -10,12 +10,12 @@
* 起動時の実行
* 再起動
* レプリケーション(実行中のプロセス数)
* メモリ
* メモリ
* 開始前の事前のステップ
これらが**デプロイメント**にどのような影響を与えるかを見ていきましょう。
最終的な目的は、**安全な方法で**APIクライアントに**サービスを提供**し、**中断を回避**するだけでなく、**計算リソース**(例えばリモートサーバー/仮想マシン)を可能な限り効率的に使用することです。🚀
最終的な目的は、**安全な方法で**APIクライアントに**サービスを提供**し、**中断を回避**するだけでなく、**計算リソース**(例えばリモートサーバー/仮想マシン)を可能な限り効率的に使用することです。 🚀
この章では前述した**コンセプト**についてそれぞれ説明します。
@@ -27,16 +27,16 @@
しかし、今はこれらの重要な**コンセプトに基づくアイデア**を確認しましょう。これらのコンセプトは、他のどのタイプのWeb APIにも当てはまります。💡
## セキュリティ - HTTPS
## セキュリティ - HTTPS { #security-https }
<!-- NOTE: https.md written in Japanese does not exist, so it redirects to English one -->
[前チャプターのHTTPSについて](https.md){.internal-link target=_blank}では、HTTPSがどのようにAPIを暗号化するのかについて学びました。
通常、アプリケーションサーバにとって**外部の**コンポーネントである**TLS Termination Proxy**によって提供されることが一般的です。このプロキシは通信の暗号化を担当します。
さらにセキュアな通信において、HTTPS証明書の定期的な更新を行いますが、これはTLS Termination Proxyと同じコンポーネントが担当することもあれば、別のコンポーネントが担当することもあります。
さらに、HTTPS証明書の更新を担当するものが必要で、同じコンポーネントが担当することもあれば、別のコンポーネントが担当することもあります。
### HTTPS 用ツールの例
### HTTPS 用ツールの例 { #example-tools-for-https }
TLS Termination Proxyとして使用できるツールには以下のようなものがあります
* Traefik
@@ -59,11 +59,11 @@ TLS Termination Proxyとして使用できるツールには以下のような
次に考慮すべきコンセプトは、実際のAPIを実行するプログラムUvicornに関連するものすべてです。
## プログラム と プロセス
## プログラム と プロセス { #program-and-process }
私たちは「**プロセス**」という言葉についてたくさん話すので、その意味や「**プログラム**」という言葉との違いを明確にしておくと便利です。
### プログラムとは何か
### プログラムとは何か { #what-is-a-program }
**プログラム**という言葉は、一般的にいろいろなものを表現するのに使われます:
@@ -71,7 +71,7 @@ TLS Termination Proxyとして使用できるツールには以下のような
* OSによって実行することができるファイル例: `python`, `python.exe` or `uvicorn`
* OS上で**実行**している間、CPUを使用し、メモリ上に何かを保存する特定のプログラム**プロセス**とも呼ばれる)
### プロセスとは何か
### プロセスとは何か { #what-is-a-process }
**プロセス**という言葉は通常、より具体的な意味で使われ、OSで実行されているものだけを指します先ほどの最後の説明のように
@@ -92,27 +92,29 @@ OSの「タスク・マネージャー」や「システム・モニター」
さて、**プロセス**と**プログラム**という用語の違いを確認したところで、デプロイメントについて話を続けます。
## 起動時の実行
## 起動時の実行 { #running-on-startup }
ほとんどの場合、Web APIを作成するときは、クライアントがいつでもアクセスできるように、**常に**中断されることなく**実行される**ことを望みます。もちろん、特定の状況でのみ実行させたい特別な理由がある場合は別ですが、その時間のほとんどは、常に実行され、**利用可能**であることを望みます。
### リモートサーバー上での実行
### リモートサーバー上での実行 { #in-a-remote-server }
リモートサーバー(クラウドサーバー、仮想マシンなど)をセットアップするときにできる最も簡単なことは、ローカルで開発するときと同じように、Uvicornまたは同様のものを手動で実行することです。 この方法は**開発中**には役に立つと思われます。
リモートサーバー(クラウドサーバー、仮想マシンなど)をセットアップするときにできる最も簡単なことは、ローカルで開発するときと同じように、`fastapi run`Uvicornを使用します同様のものを手動で実行することです。
そしてこれは動作し、**開発中**には役に立つでしょう。
しかし、サーバーへの接続が切れた場合、**実行中のプロセス**はおそらくダウンしてしまうでしょう。
そしてサーバーが再起動された場合(アップデートやクラウドプロバイダーからのマイグレーションの後など)、おそらくあなたはそれに**気づかないでしょう**。そのため、プロセスを手動で再起動しなければならないことすら気づかないでしょう。つまり、APIはダウンしたままなのです。😱
### 起動時に自動的に実行
### 起動時に自動的に実行 { #run-automatically-on-startup }
一般的に、サーバープログラムUvicornなどはサーバー起動時に自動的に開始され、**人の介入**を必要とせずに、APIと一緒にプロセスが常に実行されるようにしたいと思われますUvicornがFastAPIアプリを実行するなど
### 別のプログラムの用意
### 別のプログラムの用意 { #separate-program }
これを実現するために、通常は**別のプログラム**を用意し、起動時にアプリケーションが実行されるようにします。そして多くの場合、他のコンポーネントやアプリケーション、例えばデータベースも実行されるようにします。
### 起動時に実行するツールの例
### 起動時に実行するツールの例 { #example-tools-to-run-at-startup }
実行するツールの例をいくつか挙げます:
@@ -127,31 +129,33 @@ OSの「タスク・マネージャー」や「システム・モニター」
次の章で、より具体的な例を挙げていきます。
## 再起動
## 再起動 { #restarts }
起動時にアプリケーションが実行されることを確認するのと同様に、失敗後にアプリケーションが**再起動**されることも確認したいと思われます。
### 我々は間違いを犯す
### 我々は間違いを犯す { #we-make-mistakes }
私たち人間は常に**間違い**を犯します。ソフトウェアには、ほとんど常に**バグ**があらゆる箇所に隠されています。🐛
### 小さなエラーは自動的に処理される
そして私たち開発者は、それらのバグを見つけたり新しい機能を実装したりしながらコードを改善し続けます(新しいバグも追加してしまうかもしれません😅)。
### 小さなエラーは自動的に処理される { #small-errors-automatically-handled }
FastAPIでWeb APIを構築する際に、コードにエラーがある場合、FastAPIは通常、エラーを引き起こした単一のリクエストにエラーを含めます。🛡
クライアントはそのリクエストに対して**500 Internal Server Error**を受け取りますが、アプリケーションは完全にクラッシュするのではなく、次のリクエストのために動作を続けます。
### 重大なエラー - クラッシュ
### 重大なエラー - クラッシュ { #bigger-errors-crashes }
しかしながら、**アプリケーション全体をクラッシュさせるようなコードを書いて**UvicornとPythonをクラッシュさせるようなケースもあるかもしれません。💥
それでも、ある箇所でエラーが発生したからといって、アプリケーションを停止させたままにしたくないでしょう。 少なくとも壊れていない*パスオペレーション*については、**実行し続けたい**はずです。
それでも、ある箇所でエラーが発生したからといって、アプリケーションを停止させたままにしたくないでしょう。 少なくとも壊れていない*path operation*については、**実行し続けたい**はずです。
### クラッシュ後の再起動
### クラッシュ後の再起動 { #restart-after-crash }
しかし、実行中の**プロセス**をクラッシュさせるような本当にひどいエラーの場合、少なくとも2〜3回ほどプロセスを**再起動**させる外部コンポーネントが必要でしょう。
/// tip
/// tip | 豆知識
...とはいえ、アプリケーション全体が**すぐにクラッシュする**のであれば、いつまでも再起動し続けるのは意味がないでしょう。しかし、その場合はおそらく開発中か少なくともデプロイ直後に気づくと思われます。
@@ -161,7 +165,7 @@ FastAPIでWeb APIを構築する際に、コードにエラーがある場合、
あなたはおそらく**外部コンポーネント**がアプリケーションの再起動を担当することを望むと考えます。 なぜなら、その時点でUvicornとPythonを使った同じアプリケーションはすでにクラッシュしており、同じアプリケーションの同じコードに対して何もできないためです。
### 自動的に再起動するツールの例
### 自動的に再起動するツールの例 { #example-tools-to-restart-automatically }
ほとんどの場合、前述した**起動時にプログラムを実行する**ために使用されるツールは、自動で**再起動**することにも利用されます。
@@ -176,19 +180,19 @@ FastAPIでWeb APIを構築する際に、コードにエラーがある場合、
* クラウドプロバイダーがサービスの一部として内部的に処理
* そのほか...
## レプリケーション - プロセスとメモリ
## レプリケーション - プロセスとメモリ { #replication-processes-and-memory }
FastAPI アプリケーションでは、Uvicorn のようなサーバープログラムを使用し、**1つのプロセス**で1度に複数のクライアントに同時に対応できます。
FastAPI アプリケーションでは、Uvicorn を実行する `fastapi` コマンドのようなサーバープログラムを使用し、**1つのプロセス**で1度に複数のクライアントに同時に対応できます。
しかし、多くの場合、複数のワーカー・プロセスを同時に実行したいと考えるでしょう。
### 複数のプロセス - Worker
### 複数のプロセス - Worker { #multiple-processes-workers }
クライアントの数が単一のプロセスで処理できる数を超えており(たとえば仮想マシンがそれほど大きくない場合)、かつサーバーの CPU に**複数のコア**がある場合、同じアプリケーションで同時に**複数のプロセス**を実行させ、すべてのリクエストを分散させることができます。
同じAPIプログラムの**複数のプロセス**を実行する場合、それらは一般的に**Workerワーカー**と呼ばれます。
### ワーカー・プロセス と ポート
### ワーカー・プロセス と ポート { #worker-processes-and-ports }
<!-- NOTE: https.md written in Japanese does not exist, so it redirects to English one -->
[HTTPSについて](https.md){.internal-link target=_blank}のドキュメントで、1つのサーバーで1つのポートとIPアドレスの組み合わせでリッスンできるのは1つのプロセスだけであることを覚えていますでしょうか
@@ -197,13 +201,13 @@ FastAPI アプリケーションでは、Uvicorn のようなサーバープロ
そのため、**複数のプロセス**を同時に持つには**ポートでリッスンしている単一のプロセス**が必要であり、それが何らかの方法で各ワーカー・プロセスに通信を送信することが求められます。
### プロセスあたりのメモリ
### プロセスあたりのメモリ { #memory-per-process }
さて、プログラムがメモリにロードする際には、例えば機械学習モデルや大きなファイルの内容を変数に入れたりする場合では、**サーバーのメモリRAM**を少し消費します。
そして複数のプロセスは通常、**メモリを共有しません**。これは、実行中の各プロセスがそれぞれ独自の変数やメモリ等を持っていることを意味します。つまり、コード内で大量のメモリを消費している場合、**各プロセス**は同等の量のメモリを消費することになります。
### サーバーメモリ
### サーバーメモリ { #server-memory }
例えば、あなたのコードが **1GBのサイズの機械学習モデル**をロードする場合、APIで1つのプロセスを実行すると、少なくとも1GBのRAMを消費します。
@@ -211,7 +215,7 @@ FastAPI アプリケーションでは、Uvicorn のようなサーバープロ
リモートサーバーや仮想マシンのRAMが3GBしかない場合、4GB以上のRAMをロードしようとすると問題が発生します。🚨
### 複数プロセス - 例
### 複数プロセス - 例 { #multiple-processes-an-example }
この例では、2つの**ワーカー・プロセス**を起動し制御する**マネージャー・ プロセス**があります。
@@ -227,7 +231,7 @@ FastAPI アプリケーションでは、Uvicorn のようなサーバープロ
毎回同程度の計算を行うAPIがあり、多くのクライアントがいるのであれば、**CPU使用率**もおそらく**安定**するでしょう(常に急激に上下するのではなく)。
### レプリケーション・ツールと戦略の例
### レプリケーション・ツールと戦略の例 { #examples-of-replication-tools-and-strategies }
これを実現するにはいくつかのアプローチがありますが、具体的な戦略については次の章(Dockerやコンテナの章など)で詳しく説明します。
@@ -237,25 +241,22 @@ FastAPI アプリケーションでは、Uvicorn のようなサーバープロ
考えられる組み合わせと戦略をいくつか紹介します:
* **Gunicorn**が**Uvicornワーカー**を管理
* Gunicornは**IP**と**ポート**をリッスンする**プロセスマネージャ**で、レプリケーションは**複数のUvicornワーカー・プロセス**を持つことによって行われる。
* **Uvicorn**が**Uvicornワーカー**を管理
* `--workers` を指定した **Uvicorn**
* 1つのUvicornの**プロセスマネージャー**が**IP**と**ポート**をリッスンし、**複数のUvicornワーカー・プロセス**を起動する。
* **Kubernetes**やその他の分散**コンテナ・システム**
* **Kubernetes**レイヤーの何かが**IP**と**ポート**をリッスンする。レプリケーションは、**複数のコンテナ**にそれぞれ**1つのUvicornプロセス**を実行させることで行われる。
* **クラウド・サービス**によるレプリケーション
* クラウド・サービスはおそらく**あなたのためにレプリケーションを処理**します。**実行するプロセス**や使用する**コンテナイメージ**を定義できるかもしれませんが、いずれにせよ、それはおそらく**単一のUvicornプロセス**であり、クラウドサービスはそのレプリケーションを担当するでしょう。
/// tip
/// tip | 豆知識
これらの**コンテナ**やDockerそしてKubernetesに関する項目が、まだあまり意味をなしていなくても心配しないでください。
<!-- NOTE: the current version of docker.md is outdated compared to English one. -->
コンテナ・イメージ、Docker、Kubernetesなどについては、の章で詳しく説明します: [コンテナ内のFastAPI - Docker](docker.md){.internal-link target=_blank}.
コンテナ・イメージ、Docker、Kubernetesなどについては、将来の章で詳しく説明します: [コンテナ内のFastAPI - Docker](docker.md){.internal-link target=_blank}.
///
## 開始前の事前のステップ
## 開始前の事前のステップ { #previous-steps-before-starting }
アプリケーションを**開始する前**に、いくつかのステップを実行したい場合が多くあります。
@@ -271,7 +272,7 @@ FastAPI アプリケーションでは、Uvicorn のようなサーバープロ
もちろん、事前のステップを何度も実行しても問題がない場合もあり、その際は対処がかなり楽になります。
/// tip
/// tip | 豆知識
また、セットアップによっては、アプリケーションを開始する前の**事前のステップ**が必要ない場合もあることを覚えておいてください。
@@ -279,7 +280,7 @@ FastAPI アプリケーションでは、Uvicorn のようなサーバープロ
///
### 事前ステップの戦略例
### 事前ステップの戦略例 { #examples-of-previous-steps-strategies }
これは**システムを**デプロイする方法に**大きく依存**するだろうし、おそらくプログラムの起動方法や再起動の処理などにも関係してくるでしょう。
@@ -289,14 +290,13 @@ FastAPI アプリケーションでは、Uvicorn のようなサーバープロ
* 事前のステップを実行し、アプリケーションを起動するbashスクリプト
* 利用するbashスクリプトを起動再起動したり、エラーを検出したりする方法は以前として必要になるでしょう。
/// tip
/// tip | 豆知識
<!-- NOTE: the current version of docker.md is outdated compared to English one. -->
コンテナを使った具体的な例については、次の章で紹介します: [コンテナ内のFastAPI - Docker](docker.md){.internal-link target=_blank}.
コンテナを使った具体的な例については、将来の章で紹介します: [コンテナ内のFastAPI - Docker](docker.md){.internal-link target=_blank}.
///
## リソースの利用
## リソースの利用 { #resource-utilization }
あなたのサーバーは**リソース**であり、プログラムを実行しCPUの計算時間や利用可能なRAMメモリを消費または**利用**することができます。
@@ -319,7 +319,7 @@ FastAPI アプリケーションでは、Uvicorn のようなサーバープロ
`htop`のような単純なツールを使って、サーバーで使用されているCPUやRAM、あるいは各プロセスで使用されている量を見ることができます。あるいは、より複雑な監視ツールを使って、サーバに分散して使用することもできます。
## まとめ
## まとめ { #recap }
アプリケーションのデプロイ方法を決定する際に、考慮すべきであろう主要なコンセプトのいくつかを紹介していきました:
@@ -327,7 +327,7 @@ FastAPI アプリケーションでは、Uvicorn のようなサーバープロ
* 起動時の実行
* 再起動
* レプリケーション(実行中のプロセス数)
* メモリ
* メモリ
* 開始前の事前ステップ
これらの考え方とその適用方法を理解することで、デプロイメントを設定したり調整したりする際に必要な直感的な判断ができるようになるはずです。🤓

View File

@@ -1,20 +1,17 @@
# コンテナ内のFastAPI - Docker
# コンテナ内のFastAPI - Docker { #fastapi-in-containers-docker }
FastAPIアプリケーションをデプロイする場合、一般的なアプローチは**Linuxコンテナ・イメージ**をビルドすることです。
基本的には <a href="https://www.docker.com/" class="external-link" target="_blank">**Docker**</a>を用いて行われます。生成されたコンテナ・イメージは、いくつかの方法のいずれかでデプロイできます。
FastAPIアプリケーションをデプロイする場合、一般的なアプローチは**Linuxコンテナ・イメージ**をビルドすることです。基本的には <a href="https://www.docker.com/" class="external-link" target="_blank">**Docker**</a>を用いて行われます。生成されたコンテナ・イメージは、いくつかの方法のいずれかでデプロイできます。
Linuxコンテナの使用には、**セキュリティ**、**反復可能性(レプリカビリティ)**、**シンプリシティ**など、いくつかの利点があります。
/// tip
/// tip | 豆知識
TODO: なぜか遷移できない
お急ぎで、すでにこれらの情報をご存じですか? [以下の`Dockerfile`の箇所👇](#build-a-docker-image-for-fastapi)へジャンプしてください。
///
<details>
<summary>Dockerfile プレビュー 👀</summary>
<summary>Dockerfile Preview 👀</summary>
```Dockerfile
FROM python:3.9
@@ -27,15 +24,15 @@ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
COPY ./app /code/app
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
CMD ["fastapi", "run", "app/main.py", "--port", "80"]
# If running behind a proxy like Nginx or Traefik add --proxy-headers
# CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80", "--proxy-headers"]
# CMD ["fastapi", "run", "app/main.py", "--port", "80", "--proxy-headers"]
```
</details>
## コンテナとは何か
## コンテナとは何か { #what-is-a-container }
コンテナ主にLinuxコンテナは、同じシステム内の他のコンテナ他のアプリケーションやコンポーネントから隔離された状態を保ちながら、すべての依存関係や必要なファイルを含むアプリケーションをパッケージ化する非常に**軽量**な方法です。
@@ -45,7 +42,7 @@ Linuxコンテナは、ホストマシン、仮想マシン、クラウドサ
コンテナはまた、独自の**分離された**実行プロセス通常は1つのプロセスのみや、ファイルシステム、ネットワークを持ちます。 このことはデプロイ、セキュリティ、開発などを簡素化させます。
## コンテナ・イメージとは何か
## コンテナ・イメージとは何か { #what-is-a-container-image }
**コンテナ**は、**コンテナ・イメージ**から実行されます。
@@ -53,23 +50,17 @@ Linuxコンテナは、ホストマシン、仮想マシン、クラウドサ
保存された静的コンテンツである「**コンテナイメージ**」とは対照的に、「**コンテナ**」は通常、実行中のインスタンス、つまり**実行**されているものを指します。
**コンテナ**が起動され実行されるとき(**コンテナイメージ**から起動されるとき)、ファイルや環境変数などが作成されたり変更されたりする可能性があります。
これらの変更はそのコンテナ内にのみ存在しますが、基盤となるコンテナ・イメージには残りません(ディスクに保存されません)。
**コンテナ**が起動され実行されるとき(**コンテナイメージ**から起動されるとき)、ファイルや環境変数などが作成されたり変更されたりする可能性があります。これらの変更はそのコンテナ内にのみ存在しますが、基盤となるコンテナ・イメージには残りません(ディスクに保存されません)。
コンテナイメージは **プログラム** ファイルやその内容、例えば `python``main.py` ファイルに匹敵します。
そして、**コンテナ**自体は(**コンテナイメージ**とは対照的に)イメージをもとにした実際の実行中のインスタンスであり、**プロセス**に匹敵します。
そして、**コンテナ**自体は(**コンテナイメージ**とは対照的に)イメージをもとにした実際の実行中のインスタンスであり、**プロセス**に匹敵します。実際、コンテナが実行されているのは、**プロセスが実行されている**ときだけです(通常は単一のプロセスだけです)。 コンテナ内で実行中のプロセスがない場合、コンテナは停止します。
実際、コンテナが実行されているのは、**プロセスが実行されている**ときだけです(通常は単一のプロセスだけです)。 コンテナ内で実行中のプロセスがない場合、コンテナは停止します。
## コンテナ・イメージ
## コンテナ・イメージ { #container-images }
Dockerは、**コンテナ・イメージ**と**コンテナ**を作成・管理するための主要なツールの1つです。
そして、DockerにはDockerイメージコンテナを共有する<a href="https://hub.docker.com/" class="external-link" target="_blank">Docker Hub</a>というものがあります。
Docker Hubは 多くのツールや環境、データベース、アプリケーションに対応している予め作成された**公式のコンテナ・イメージ**をパブリックに提供しています。
そして、多くのツールや環境、データベース、アプリケーションに対応している予め作成された**公式のコンテナ・イメージ**をパブリックに提供している<a href="https://hub.docker.com/" class="external-link" target="_blank">Docker Hub</a>というものがあります。
例えば、公式イメージの1つに<a href="https://hub.docker.com/_/python" class="external-link" target="_blank">Python Image</a>があります。
@@ -88,7 +79,7 @@ Docker Hubは 多くのツールや環境、データベース、アプリケー
すべてのコンテナ管理システムDockerやKubernetesなどには、こうしたネットワーキング機能が統合されています。
## コンテナとプロセス
## コンテナとプロセス { #containers-and-processes }
通常、**コンテナ・イメージ**はそのメタデータに**コンテナ**の起動時に実行されるデフォルトのプログラムまたはコマンドと、そのプログラムに渡されるパラメータを含みます。コマンドラインでの操作とよく似ています。
@@ -100,7 +91,7 @@ Docker Hubは 多くのツールや環境、データベース、アプリケー
しかし、**少なくとも1つの実行中のプロセス**がなければ、実行中のコンテナを持つことはできないです。メイン・プロセスが停止すれば、コンテナも停止します。
## Build a Docker Image for FastAPI
## FastAPI用のDockerイメージをビルドする { #build-a-docker-image-for-fastapi }
ということで、何か作りましょう!🚀
@@ -112,7 +103,7 @@ FastAPI用の**Dockerイメージ**を、**公式Python**イメージに基づ
* **Raspberry Pi**で実行する場合
* コンテナ・イメージを実行してくれるクラウド・サービスなどを利用する場合
### パッケージ要件package requirements
### パッケージ要件 { #package-requirements }
アプリケーションの**パッケージ要件**は通常、何らかのファイルに記述されているはずです。
@@ -125,9 +116,8 @@ FastAPI用の**Dockerイメージ**を、**公式Python**イメージに基づ
例えば、`requirements.txt` は次のようになります:
```
fastapi>=0.68.0,<0.69.0
pydantic>=1.8.0,<2.0.0
uvicorn>=0.15.0,<0.16.0
fastapi[standard]>=0.113.0,<0.114.0
pydantic>=2.7.0,<3.0.0
```
そして通常、例えば `pip` を使ってこれらのパッケージの依存関係をインストールします:
@@ -137,28 +127,24 @@ uvicorn>=0.15.0,<0.16.0
```console
$ pip install -r requirements.txt
---> 100%
Successfully installed fastapi pydantic uvicorn
Successfully installed fastapi pydantic
```
</div>
/// info
/// info | 情報
パッケージの依存関係を定義しインストールするためのフォーマットやツールは他にもあります。
Poetryを使った例は、後述するセクションでご紹介します。👇
///
### **FastAPI**コードを作成する
### **FastAPI**コードを作成する { #create-the-fastapi-code }
* `app` ディレクトリを作成し、その中に入ります
* 空のファイル `__init__.py` を作成します
* `main.py` ファイルを作成します:
* `app` ディレクトリを作成し、その中に入ります
* 空のファイル `__init__.py` を作成します
* 次の内容で `main.py` ファイルを作成します:
```Python
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@@ -170,32 +156,32 @@ 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}
```
### Dockerfile
### Dockerfile { #dockerfile }
同じプロジェクト・ディレクトリに`Dockerfile`というファイルを作成します:
```{ .dockerfile .annotate }
# (1)
# (1)!
FROM python:3.9
# (2)
# (2)!
WORKDIR /code
# (3)
# (3)!
COPY ./requirements.txt /code/requirements.txt
# (4)
# (4)!
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
# (5)
# (5)!
COPY ./app /code/app
# (6)
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
# (6)!
CMD ["fastapi", "run", "app/main.py", "--port", "80"]
```
1. 公式のPythonベースイメージから始めます
@@ -211,9 +197,10 @@ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
このファイルは**頻繁には変更されない**ので、Dockerはこのステップではそれを検知し**キャッシュ**を使用し、次のステップでもキャッシュを有効にします。
4. 要件ファイルにあるパッケージの依存関係をインストールします
`--no-cache-dir` オプションはダウンロードしたパッケージをローカルに保存しないように `pip` に指示します。これは、同じパッケージをインストールするために `pip` を再度実行する場合にのみ有効ですが、コンテナで作業する場合はそうではないです。
/// note
/// note | 備考
`--no-cache-dir`は`pip`に関連しているだけで、Dockerやコンテナとは何の関係もないです。
@@ -225,26 +212,56 @@ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
このステップでキャッシュを使用すると、開発中にイメージを何度もビルドする際に、**毎回**すべての依存関係を**ダウンロードしてインストールする**代わりに多くの**時間**を**節約**できます。
5. ./app` ディレクトリを `/code` ディレクトリの中にコピーする。
5. `./app` ディレクトリを `/code` ディレクトリの中にコピーする。
これには**最も頻繁に変更される**すべてのコードが含まれているため、Dockerの**キャッシュ**は**これ以降のステップ**に簡単に使用されることはありません。
そのため、コンテナイメージのビルド時間を最適化するために、`Dockerfile`の **最後** にこれを置くことが重要です。
6. `uvicorn`サーバーを実行するための**コマンド**を設定します
6. 内部でUvicornを使用する `fastapi run` を使うための**コマンド**を設定します
`CMD` は文字列のリストを取り、それぞれの文字列はスペースで区切られたコマンドラインに入力するものです。
このコマンドは **現在の作業ディレクトリ**から実行され、上記の `WORKDIR /code` にて設定した `/code` ディレクトリと同じです。
そのためプログラムは `/code` で開始しその中にあなたのコードがある `./app` ディレクトリがあるので、**Uvicorn** は `app.main` から `app` を参照し、**インポート** することができます。
/// tip | 豆知識
/// tip
コード内の"+"の吹き出しをクリックして、各行が何をするのかをレビューしてください。👆
コード内の各番号バブルをクリックして、各行が何をするのかをレビューしてください。👆
///
/// warning | 注意
以下で説明する通り、`CMD` 命令は**常に** **exec形式**を使用してください。
///
#### `CMD` を使う - Exec形式 { #use-cmd-exec-form }
Docker命令 <a href="https://docs.docker.com/reference/dockerfile/#cmd" class="external-link" target="_blank">`CMD`</a> は2つの形式で書けます
✅ **Exec** 形式:
```Dockerfile
# ✅ Do this
CMD ["fastapi", "run", "app/main.py", "--port", "80"]
```
⛔️ **Shell** 形式:
```Dockerfile
# ⛔️ Don't do this
CMD fastapi run app/main.py --port 80
```
FastAPIが正常にシャットダウンでき、[lifespan events](../advanced/events.md){.internal-link target=_blank}がトリガーされるように、常に **exec** 形式を使用してください。
詳しくは、<a href="https://docs.docker.com/reference/dockerfile/#shell-and-exec-form" class="external-link" target="_blank">shell形式とexec形式に関するDockerドキュメント</a>をご覧ください。
これは `docker compose` を使用する場合にかなり目立つことがあります。より技術的な詳細は、このDocker ComposeのFAQセクションをご覧ください<a href="https://docs.docker.com/compose/faq/#why-do-my-services-take-10-seconds-to-recreate-or-stop" class="external-link" target="_blank">Why do my services take 10 seconds to recreate or stop?</a>。
#### ディレクトリ構造 { #directory-structure }
これで、次のようなディレクトリ構造になるはずです:
```
@@ -256,17 +273,15 @@ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
└── requirements.txt
```
#### TLS Termination Proxyの裏側
#### TLS Termination Proxyの裏側 { #behind-a-tls-termination-proxy }
Nginx や Traefik のような TLS Termination Proxy (ロードバランサ) の後ろでコンテナを動かしている場合は、`--proxy-headers`オプションを追加します。
このオプションは、Uvicornにプロキシ経由でHTTPSで動作しているアプリケーションに対して、送信されるヘッダを信頼するよう指示します。
Nginx や Traefik のような TLS Termination Proxy (ロードバランサ) の後ろでコンテナを動かしている場合は、`--proxy-headers`オプションを追加します。これにより、FastAPI CLI経由でUvicornに対して、そのプロキシから送信されるヘッダを信頼し、アプリケーションがHTTPSの裏で実行されていることなどを示すよう指示します。
```Dockerfile
CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"]
CMD ["fastapi", "run", "app/main.py", "--proxy-headers", "--port", "80"]
```
#### Dockerキャッシュ
#### Dockerキャッシュ { #docker-cache }
この`Dockerfile`には重要なトリックがあり、まず**依存関係だけのファイル**をコピーします。その理由を説明します。
@@ -300,11 +315,11 @@ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
COPY ./app /code/app
```
### Dockerイメージをビルドする
### Dockerイメージをビルドする { #build-the-docker-image }
すべてのファイルが揃ったので、コンテナ・イメージをビルドしましょう。
* プロジェクトディレクトリに移動します(`Dockerfile`がある場所で、`app`ディレクトリがあります)
* プロジェクトディレクトリに移動します(`Dockerfile`がある場所で、`app`ディレクトリがあります)
* FastAPI イメージをビルドします:
<div class="termy">
@@ -317,7 +332,7 @@ $ docker build -t myimage .
</div>
/// tip
/// tip | 豆知識
末尾の `.` に注目してほしいです。これは `./` と同じ意味です。 これはDockerにコンテナイメージのビルドに使用するディレクトリを指示します。
@@ -325,7 +340,7 @@ $ docker build -t myimage .
///
### Dockerコンテナの起動する
### Dockerコンテナの起動する { #start-the-docker-container }
* イメージに基づいてコンテナを実行します:
@@ -337,7 +352,7 @@ $ docker run -d --name mycontainer -p 80:80 myimage
</div>
## 確認する
## 確認する { #check-it }
Dockerコンテナの<a href="http://192.168.99.100/items/5?q=somequery" class="external-link" target="_blank">http://192.168.99.100/items/5?q=somequery</a> や <a href="http://127.0.0.1/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1/items/5?q=somequery</a> (またはそれに相当するDockerホストを使用したものといったURLで確認できるはずです。
@@ -347,7 +362,7 @@ Dockerコンテナの<a href="http://192.168.99.100/items/5?q=somequery" class="
{"item_id": 5, "q": "somequery"}
```
## インタラクティブなAPIドキュメント
## インタラクティブなAPIドキュメント { #interactive-api-docs }
これらのURLにもアクセスできます: <a href="http://192.168.99.100/docs" class="external-link" target="_blank">http://192.168.99.100/docs</a> や <a href="http://127.0.0.1/docs" class="external-link" target="_blank">http://127.0.0.1/docs</a> (またはそれに相当するDockerホストを使用したもの
@@ -355,7 +370,7 @@ Dockerコンテナの<a href="http://192.168.99.100/items/5?q=somequery" class="
![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
## 代替のAPIドキュメント
## 代替のAPIドキュメント { #alternative-api-docs }
また、<a href="http://192.168.99.100/redoc" class="external-link" target="_blank">http://192.168.99.100/redoc</a> や <a href="http://127.0.0.1/redoc" class="external-link" target="_blank">http://127.0.0.1/redoc</a> (またはそれに相当するDockerホストを使用したものにもアクセスできます。
@@ -363,9 +378,10 @@ Dockerコンテナの<a href="http://192.168.99.100/items/5?q=somequery" class="
![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
## 単一ファイルのFastAPIでDockerイメージをビルドする
## 単一ファイルのFastAPIでDockerイメージをビルドする { #build-a-docker-image-with-a-single-file-fastapi }
FastAPI が単一のファイル、例えば `./app` ディレクトリのない `main.py` の場合、ファイル構造は次のようになります:
```
.
├── Dockerfile
@@ -384,43 +400,43 @@ COPY ./requirements.txt /code/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
# (1)
# (1)!
COPY ./main.py /code/
# (2)
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
# (2)!
CMD ["fastapi", "run", "main.py", "--port", "80"]
```
1. main.py`ファイルを `/code` ディレクトリに直接コピーします。
1. `main.py`ファイルを `/code` ディレクトリに直接コピーします`./app` ディレクトリなし)
2. Uvicornを実行し、`main`から`app`オブジェクトをインポートするように指示します(`app.main`からインポートするのではなく)
2. 単一ファイル `main.py` 内のアプリケーションを配信するために `fastapi run` を使用します
次にUvicornコマンドを調整して、`app.main` の代わりに新しいモジュール `main` を使用し、FastAPIオブジェクトである `app` をインポートします。
`fastapi run` にファイルを渡すと、それがパッケージの一部ではなく単一ファイルであることを自動的に検出し、インポートしてFastAPIアプリを配信する方法を判断します。😎
## デプロイメントのコンセプト
## デプロイメントのコンセプト { #deployment-concepts }
コンテナという観点から、[デプロイのコンセプト](concepts.md){.internal-link target=_blank}に共通するいくつかについて、もう一度説明しましょう。
コンテナは主に、アプリケーションの**ビルドとデプロイ**のプロセスを簡素化するためのツールですが、これらの**デプロイのコンセプト**を扱うための特定のアプローチを強制するものではないです。
コンテナは主に、アプリケーションの**ビルドとデプロイ**のプロセスを簡素化するためのツールですが、これらの**デプロイのコンセプト**を扱うための特定のアプローチを強制するものではなく、いくつかの戦略があります。
**良いニュース**は、それぞれの異なる戦略には、すべてのデプロイメントのコンセプトをカバーする方法があるということです。🎉
これらの**デプロイメントのコンセプト**をコンテナの観点から見直してみましょう:
* セキュリティ - HTTPS
* HTTPS
* 起動時の実行
* 再起動
* **レプリケーション(実行中のプロセス数)**
* レプリケーション(実行中のプロセス数)
* メモリ
* 開始前の事前ステップ
## HTTPS
## HTTPS { #https }
FastAPI アプリケーションの **コンテナ・イメージ**(および後で実行中の **コンテナ**だけに焦点を当てると、通常、HTTPSは別のツールを用いて**外部で**処理されます。
例えば<a href="https://traefik.io/" class="external-link" target="_blank">Traefik</a>のように、**HTTPS**と**証明書**の**自動**取得を扱う別のコンテナである可能性もあります。
/// tip
/// tip | 豆知識
TraefikはDockerやKubernetesなどと統合されているので、コンテナ用のHTTPSの設定や構成はとても簡単です。
@@ -428,7 +444,7 @@ TraefikはDockerやKubernetesなどと統合されているので、コンテナ
あるいは、コンテナ内でアプリケーションを実行しながらクラウド・プロバイダーがサービスの1つとしてHTTPSを処理することもできます。
## 起動時および再起動時の実行
## 起動時および再起動時の実行 { #running-on-startup-and-restarts }
通常、コンテナの**起動と実行**を担当する別のツールがあります。
@@ -438,21 +454,21 @@ TraefikはDockerやKubernetesなどと統合されているので、コンテナ
コンテナを使わなければ、アプリケーションを起動時や再起動時に実行させるのは面倒で難しいかもしれません。しかし、**コンテナ**で作業する場合、ほとんどのケースでその機能はデフォルトで含まれています。✨
## レプリケーション - プロセス数
## レプリケーション - プロセス数 { #replication-number-of-processes }
**Kubernetes** や Docker Swarm モード、Nomad、あるいは複数のマシン上で分散コンテナを管理するための同様の複雑なシステムを使ってマシンの<abbr title="何らかの方法で接続され、一緒に動作するように構成されたマシンのグループ">クラスター</abbr>を構成している場合、 各コンテナでWorkerを持つGunicornのような**プロセスマネージャ**を使用する代わりに、**クラスター・レベル**で**レプリケーション**を処理したいと思うでしょう。
**Kubernetes** や Docker Swarm モード、Nomad、あるいは複数のマシン上で分散コンテナを管理するための同様の複雑なシステムを使ってマシンの<abbr title="A group of machines that are configured to be connected and work together in some way. - ある方法で接続され、連携して動作するように構成されたマシンの集まり">cluster</abbr>を構成している場合、 各コンテナでWorkerを持つUvicornのような**プロセスマネージャ**を使用する代わりに、**クラスター・レベル**で**レプリケーション**を処理したいと思うでしょう。
Kubernetesのような分散コンテナ管理システムの1つは通常、入ってくるリクエストの**ロードバランシング**をサポートしながら、**コンテナのレプリケーション**を処理する統合された方法を持っています。このことはすべて**クラスタレベル**にてです。
そのような場合、UvicornワーカーでGunicornのようなものを実行するのではなく、[上記の説明](#dockerfile)のように**Dockerイメージをゼロから**ビルドし、依存関係をインストールして、**単一のUvicornプロセス**を実行したいでしょう。
そのような場合、[上記の説明](#dockerfile)のように**Dockerイメージをゼロから**ビルドし、依存関係をインストールして、**単一のUvicornプロセス**を実行したいでしょう。複数のUvicornワーカーを使う代わりにです。
### ロードバランサー
### ロードバランサー { #load-balancer }
コンテナを使用する場合、通常はメイン・ポート**でリスニング**しているコンポーネントがあるはずです。それはおそらく、**HTTPS**を処理するための**TLS Termination Proxy**でもある別のコンテナであったり、同様のツールであったりするでしょう。
このコンポーネントはリクエストの **負荷** を受け、 (うまくいけば) その負荷を**バランスよく** ワーカーに分配するので、一般に **ロードバランサ** とも呼ばれます。
/// tip
/// tip | 豆知識
HTTPSに使われるものと同じ**TLS Termination Proxy**コンポーネントは、おそらく**ロードバランサー**にもなるでしょう。
@@ -460,7 +476,7 @@ HTTPSに使われるものと同じ**TLS Termination Proxy**コンポーネン
そしてコンテナで作業する場合、コンテナの起動と管理に使用する同じシステムには、**ロードバランサー****TLS Termination Proxy**の可能性もある)から**ネットワーク通信**HTTPリクエストなどをアプリのあるコンテナ複数可に送信するための内部ツールが既にあるはずです。
### 1つのロードバランサー - 複数のワーカーコンテナー
### 1つのロードバランサー - 複数のワーカーコンテナー { #one-load-balancer-multiple-worker-containers }
**Kubernetes**や同様の分散コンテナ管理システムで作業する場合、その内部のネットワーキングのメカニズムを使用することで、メインの**ポート**でリッスンしている単一の**ロードバランサー**が、アプリを実行している可能性のある**複数のコンテナ**に通信(リクエスト)を送信できるようになります。
@@ -470,56 +486,61 @@ HTTPSに使われるものと同じ**TLS Termination Proxy**コンポーネン
そして通常、この**ロードバランサー**は、クラスタ内の*他の*アプリケーション例えば、異なるドメインや異なるURLパスのプレフィックスの配下へのリクエストを処理することができ、その通信をクラスタ内で実行されている*他の*アプリケーションのための適切なコンテナに送信します。
### 1コンテナにつき1プロセス
### 1コンテナにつき1プロセス { #one-process-per-container }
この種のシナリオでは、すでにクラスタ・レベルでレプリケーションを処理しているため、おそらくコンテナごとに**単一のUvicornプロセス**を持ちたいでしょう。
この場合、Uvicornワーカーを持つGunicornのようなプロセスマネージャーや、Uvicornワーカーを使うUvicornは**避けたい**でしょう。**コンテナごとにUvicornのプロセスは1つだけ**にしたいでしょう(おそらく複数のコンテナが必要でしょう)。
この場合、例えばコマンドラインオプションの `--workers` で、コンテナ内に複数のワーカーを持つことは**避けたい**でしょう。**コンテナごとにUvicornのプロセスは1つだけ**にしたいでしょう(おそらく複数のコンテナが必要でしょう)。
GunicornやUvicornがUvicornワーカーを管理するように)コンテナ内に別のプロセスマネージャーを持つことは、クラスターシステムですでに対処しているであろう**不要な複雑さ**を追加するだけです。
(複数のワーカーの場合のように)コンテナ内に別のプロセスマネージャーを持つことは、クラスターシステムですでに対処しているであろう**不要な複雑さ**を追加するだけです。
### Containers with Multiple Processes and Special Cases
### 複数プロセスのコンテナと特殊なケース { #containers-with-multiple-processes-and-special-cases }
もちろん、**特殊なケース**として、**Gunicornプロセスマネージャ**を持つ**コンテナ**内で複数の**Uvicornワーカープロセス**を起動させたい場合があります。
もちろん、**特殊なケース**として、**コンテナ**内で複数の**Uvicornワーカープロセス**を起動させたい場合があります。
のような場合、**公式のDockerイメージ**を使用することができます。このイメージには、複数の**Uvicornワーカープロセス**を実行するプロセスマネージャとして**Gunicorn**が含まれており、現在のCPUコアに基づいてワーカー数を自動的に調整するためのデフォルト設定がいくつか含まれています。詳しくは後述の[Gunicornによる公式Dockerイメージ - Uvicorn](#gunicorndocker-uvicorn)で説明します
のような場合、`--workers` コマンドラインオプションを使って、実行したいワーカー数を設定できます
```{ .dockerfile .annotate }
FROM python:3.9
WORKDIR /code
COPY ./requirements.txt /code/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
COPY ./app /code/app
# (1)!
CMD ["fastapi", "run", "app/main.py", "--port", "80", "--workers", "4"]
```
1. ここでは `--workers` コマンドラインオプションを使って、ワーカー数を4に設定しています。
以下は、それが理にかなっている場合の例です:
#### シンプルなアプリケーション
#### シンプルなアプリ { #a-simple-app }
アプリケーションを**シンプル**な形で実行する場合、プロセス数の細かい調整が必要ない場合、自動化されたデフォルトを使用するだけで、コンテナ内にプロセスマネージャが必要かもしれません。例えば、公式Dockerイメージでシンプルな設定が可能です。
アプリケーションが、クラスタではなく**単一サーバ**で実行できるほど**シンプル**である場合、コンテナ内にプロセスマネージャが欲しくなることがあります。
#### Docker Compose
#### Docker Compose { #docker-compose }
Docker Composeで**シングルサーバ**(クラスタではない)にデプロイすることもできますので、共有ネットワークと**ロードバランシング**を維持しながらDocker Composeでコンテナのレプリケーションを管理する簡単な方法はないでしょう。
Docker Composeで**単一サーバ**(クラスタではない)にデプロイすることもできますので、共有ネットワークと**ロードバランシング**を維持しながらDocker Composeでコンテナのレプリケーションを管理する簡単な方法はないでしょう。
その場合、**単一のコンテナ**で、**プロセスマネージャ**が内部で**複数のワーカープロセス**を起動するようにします。
#### Prometheusとその他の理由
また、**1つのコンテナ**に**1つのプロセス**を持たせるのではなく、**1つのコンテナ**に**複数のプロセス**を持たせる方が簡単だという**他の理由**もあるでしょう。
例えば、(セットアップにもよりますが)Prometheusエクスポーターのようなツールを同じコンテナ内に持つことができます。
この場合、**複数のコンテナ**があると、デフォルトでは、Prometheusが**メトリクスを**読みに来たとき、すべてのレプリケートされたコンテナの**蓄積されたメトリクス**を取得するのではなく、毎回**単一のコンテナ**(その特定のリクエストを処理したコンテナ)のものを取得することになります。
その場合、**複数のプロセス**を持つ**1つのコンテナ**を用意し、同じコンテナ上のローカルツール例えばPrometheusエクスポーターがすべての内部プロセスのPrometheusメトリクスを収集し、その1つのコンテナ上でそれらのメトリクスを公開する方がシンプルかもしれません。
---
重要なのは、盲目的に従わなければならない普遍のルールはないということです。
これらのアイデアは、**あなた自身のユースケース**を評価し、あなたのシステムに最適なアプローチを決定するために使用することができます:
重要なのは、これらのどれも、盲目的に従わなければならない「**絶対的なルール**」ではないということです。これらのアイデアは、**あなた自身のユースケース**を評価し、あなたのシステムに最適なアプローチを決定するために使用できます。次の概念をどう管理するかを確認してください:
* セキュリティ - HTTPS
* 起動時の実行
* 再起動
* **レプリケーション(実行中のプロセス数)**
* レプリケーション(実行中のプロセス数)
* メモリ
* 開始前の事前ステップ
## メモリ
## メモリ { #memory }
コンテナごとに**単一のプロセスを実行する**と、それらのコンテナレプリケートされている場合は1つ以上によって消費される多かれ少なかれ明確に定義された、安定し制限された量のメモリを持つことになります。
@@ -531,109 +552,47 @@ Docker Composeで**シングルサーバ**(クラスタではない)にデ
しかし、**多くのメモリを使用**している場合(たとえば**機械学習**モデルなど)、どれだけのメモリを消費しているかを確認し、**各マシンで実行するコンテナの数**を調整する必要があります(そしておそらくクラスタにマシンを追加します)。
**コンテナごとに複数のプロセス**を実行する場合たとえば公式のDockerイメージで、起動するプロセスの数が**利用可能なメモリ以上に消費しない**ようにする必要があります。
**コンテナごとに複数のプロセス**を実行する場合、起動するプロセスの数が**利用可能なメモリ以上に消費しない**ようにする必要があります。
## 開始前の事前ステップとコンテナ
## 開始前の事前ステップとコンテナ { #previous-steps-before-starting-and-containers }
コンテナDockerやKubernetesなどを使っている場合、主に2つのアプローチがあります。
### 複数のコンテナ
### 複数のコンテナ { #multiple-containers }
複数の**コンテナ**があり、おそらくそれぞれが**単一のプロセス**を実行している場合(**Kubernetes**クラスタなど)、レプリケートされたワーカーコンテナを実行する**前に**、単一のコンテナで**事前のステップ**の作業を行う**別のコンテナ**を持ちたいと思うでしょう。
複数の**コンテナ**があり、おそらくそれぞれが**単一のプロセス**を実行している場合(例えば、**Kubernetes**クラスタなど)、レプリケートされたワーカーコンテナを実行する**前に**、単一のコンテナで**事前のステップ**の作業を行う**別のコンテナ**を持ちたいと思うでしょう。
/// info
/// info | 情報
もしKubernetesを使用している場合, これはおそらく<a href="https://kubernetes.io/docs/concepts/workloads/pods/init-containers/" class="external-link" target="_blank">Init コンテナ</a>でしょう。
もしKubernetesを使用している場合, これはおそらく<a href="https://kubernetes.io/docs/concepts/workloads/pods/init-containers/" class="external-link" target="_blank">Init Container</a>でしょう。
///
ユースケースが事前のステップを**並列で複数回**実行するのに問題がない場合(例:データベースの準備チェック)、メインプロセスを開始する前に、それらのステップを各コンテナに入れること可能です。
ユースケースが事前のステップを**並列で複数回**実行するのに問題がない場合(例:データベースマイグレーションを実行するのではなく、データベースの準備ができたかをチェックするだけの場合)、メインプロセスを開始する前に、それらのステップを各コンテナに入れること可能です。
### 単一コンテナ
### 単一コンテナ { #single-container }
単純なセットアップで、**単一のコンテナ**で複数の**ワーカープロセス**または1つのプロセスのみを起動する場合、アプリでプロセスを開始する直前に、同じコンテナで事前のステップを実行できます。公式Dockerイメージは、内部的にこれをサポートしています。
単純なセットアップで、**単一のコンテナ**で複数の**ワーカープロセス**または1つのプロセスのみを起動する場合、アプリでプロセスを開始する直前に、同じコンテナで事前のステップを実行できます。
## Gunicornによる公式Dockerイメージ - Uvicorn
### ベースDockerイメージ { #base-docker-image }
前の章で詳しく説明したように、Uvicornワーカーで動作するGunicornを含む公式のDockerイメージがあります [Server Workers - Gunicorn と Uvicorn](server-workers.md){.internal-link target=_blank}で詳しく説明しています。
以前は、公式のFastAPI Dockerイメージがありました<a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>。しかし、現在は非推奨です。⛔️
このイメージは、主に上記で説明した状況で役に立つでしょう: [複数のプロセスと特殊なケースを持つコンテナContainers with Multiple Processes and Special Cases](#containers-with-multiple-processes-and-special-cases)
おそらく、このベースDockerイメージまたはその他の類似のものは**使用しない**方がよいでしょう。
* <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>.
すでに**Kubernetes**(または他のもの)を使用していて、複数の**コンテナ**で、クラスタレベルで**レプリケーション**を設定している場合。そのような場合は、上記で説明したように**ゼロから**イメージを構築する方がよいでしょう:[FastAPI用のDockerイメージをビルドする](#build-a-docker-image-for-fastapi)。
/// warning
また、複数のワーカーが必要な場合は、単純に `--workers` コマンドラインオプションを使用できます。
このベースイメージや類似のイメージは**必要ない**可能性が高いので、[上記の: FastAPI用のDockerイメージをビルドするBuild a Docker Image for FastAPI](#build-a-docker-image-for-fastapi)のようにゼロからイメージをビルドする方が良いでしょう。
/// note | 技術詳細
このDockerイメージは、Uvicornが停止したワーカーの管理と再起動をサポートしていなかった頃に作成されたため、Uvicornと一緒にGunicornを使う必要がありました。これは、GunicornにUvicornワーカープロセスの管理と再起動をさせるだけのために、かなりの複雑さを追加していました。
しかし現在は、Uvicornおよび `fastapi` コマンド)が `--workers` をサポートしているため、自分でビルドする代わりにベースDockerイメージを使う理由はありませんコード量もだいたい同じです 😅)。
///
このイメージには、利用可能なCPUコアに基づいて**ワーカー・プロセスの数**を設定する**オートチューニング**メカニズムが含まれています。
これは**賢明なデフォルト**を備えていますが、**環境変数**や設定ファイルを使ってすべての設定を変更したり更新したりすることができます。
また、スクリプトで<a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker#pre_start_path" class="external-link" target="_blank">**開始前の事前ステップ**</a>を実行することもサポートしている。
/// tip
すべての設定とオプションを見るには、Dockerイメージのページをご覧ください: <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>
///
### 公式Dockerイメージのプロセス数
このイメージの**プロセス数**は、利用可能なCPU**コア**から**自動的に計算**されます。
つまり、CPUから可能な限り**パフォーマンス**を**引き出そう**とします。
また、**環境変数**などを使った設定で調整することもできます。
しかし、プロセスの数はコンテナが実行しているCPUに依存するため、**消費されるメモリの量**もそれに依存することになります。
そのため、機械学習モデルなどで大量のメモリを消費するアプリケーションで、サーバーのCPUコアが多いが**メモリが少ない**場合、コンテナは利用可能なメモリよりも多くのメモリを使おうとすることになります。
その結果、パフォーマンスが大幅に低下する(あるいはクラッシュする)可能性があります。🚨
### Dockerfileを作成する
この画像に基づいて`Dockerfile`を作成する方法を以下に示します:
```Dockerfile
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9
COPY ./requirements.txt /app/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
COPY ./app /app
```
### より大きなアプリケーション
[複数のファイルを持つ大きなアプリケーション](../tutorial/bigger-applications.md){.internal-link target=_blank}を作成するセクションに従った場合、`Dockerfile`は次のようになります:
```Dockerfile hl_lines="7"
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9
COPY ./requirements.txt /app/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
COPY ./app /app/app
```
### いつ使うのか
おそらく、**Kubernetes**(または他のもの)を使用していて、すでにクラスタレベルで複数の**コンテナ**で**レプリケーション**を設定している場合は、この公式ベースイメージ(または他の類似のもの)は**使用すべきではありません**。
そのような場合は、上記のように**ゼロから**イメージを構築する方がよいでしょう: [FastAPI用のDockerイメージをビルドするBuild a Docker Image for FastAPI](#build-a-docker-image-for-fastapi) を参照してください。
このイメージは、主に上記の[複数のプロセスと特殊なケースを持つコンテナContainers with Multiple Processes and Special Cases](#containers-with-multiple-processes-and-special-cases)で説明したような特殊なケースで役に立ちます。
例えば、アプリケーションが**シンプル**で、CPUに応じたデフォルトのプロセス数を設定すればうまくいく場合や、クラスタレベルでレプリケーションを手動で設定する手間を省きたい場合、アプリで複数のコンテナを実行しない場合などです。
または、**Docker Compose**でデプロイし、単一のサーバで実行している場合などです。
## コンテナ・イメージのデプロイ
## コンテナ・イメージのデプロイ { #deploy-the-container-image }
コンテナDockerイメージを手に入れた後、それをデプロイするにはいくつかの方法があります。
@@ -645,104 +604,21 @@ COPY ./app /app/app
* Nomadのような別のツール
* コンテナ・イメージをデプロイするクラウド・サービス
## Poetryを利用したDockerイメージ
## `uv` を使ったDockerイメージ { #docker-image-with-uv }
もしプロジェクトの依存関係を管理するために<a href="https://python-poetry.org/" class="external-link" target="_blank">Poetry</a>を利用する場合、マルチステージビルドを使うと良いでしょう
<a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a> を使ってプロジェクトのインストールと管理をしている場合は、<a href="https://docs.astral.sh/uv/guides/integration/docker/" class="external-link" target="_blank">uv Docker guide</a>に従ってください
```{ .dockerfile .annotate }
# (1)
FROM python:3.9 as requirements-stage
# (2)
WORKDIR /tmp
# (3)
RUN pip install poetry
# (4)
COPY ./pyproject.toml ./poetry.lock* /tmp/
# (5)
RUN poetry export -f requirements.txt --output requirements.txt --without-hashes
# (6)
FROM python:3.9
# (7)
WORKDIR /code
# (8)
COPY --from=requirements-stage /tmp/requirements.txt /code/requirements.txt
# (9)
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
# (10)
COPY ./app /code/app
# (11)
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
```
1. これは最初のステージで、`requirements-stage`と名付けられます
2. `/tmp` を現在の作業ディレクトリに設定します
ここで `requirements.txt` というファイルを生成します。
3. このDockerステージにPoetryをインストールします
4. pyproject.toml``poetry.lock`ファイルを`/tmp` ディレクトリにコピーします
`./poetry.lock*`(末尾に`*`)を使用するため、そのファイルがまだ利用できない場合でもクラッシュすることはないです。
5. requirements.txt`ファイルを生成します
6. これは最後のステージであり、ここにあるものはすべて最終的なコンテナ・イメージに保存されます
7. 現在の作業ディレクトリを `/code` に設定します
8. `requirements.txt`ファイルを `/code` ディレクトリにコピーします
このファイルは前のDockerステージにしか存在しないため、`--from-requirements-stage`を使ってコピーします。
9. 生成された `requirements.txt` ファイルにあるパッケージの依存関係をインストールします
10. app` ディレクトリを `/code` ディレクトリにコピーします
11. uvicorn` コマンドを実行して、`app.main` からインポートした `app` オブジェクトを使用するように指示します
/// tip
"+"の吹き出しをクリックすると、それぞれの行が何をするのかを見ることができます
///
**Dockerステージ**は`Dockerfile`の一部で、**一時的なコンテナイメージ**として動作します。
最初のステージは **Poetryのインストール**と Poetry の `pyproject.toml` ファイルからプロジェクトの依存関係を含む**`requirements.txt`を生成**するためだけに使用されます。
この `requirements.txt` ファイルは後半の **次のステージ**で `pip` と共に使用されます。
最終的なコンテナイメージでは、**最終ステージ**のみが保存されます。前のステージは破棄されます。
Poetryを使用する場合、**Dockerマルチステージビルド**を使用することは理にかなっています。
なぜなら、最終的なコンテナイメージにPoetryとその依存関係がインストールされている必要はなく、**必要なのは**プロジェクトの依存関係をインストールするために生成された `requirements.txt` ファイルだけだからです。
そして次の(そして最終的な)ステージでは、前述とほぼ同じ方法でイメージをビルドします。
### TLS Termination Proxyの裏側 - Poetry
繰り返しになりますが、NginxやTraefikのようなTLS Termination Proxyロードバランサーの後ろでコンテナを動かしている場合は、`--proxy-headers`オプションをコマンドに追加します:
```Dockerfile
CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"]
```
## まとめ
## まとめ { #recap }
コンテナ・システム(例えば**Docker**や**Kubernetes**など)を使えば、すべての**デプロイメントのコンセプト**を扱うのがかなり簡単になります:
* セキュリティ - HTTPS
* HTTPS
* 起動時の実行
* 再起動
* **レプリケーション(実行中のプロセス数)**
* レプリケーション(実行中のプロセス数)
* メモリ
* 開始前の事前ステップ
ほとんどの場合、ベースとなるイメージは使用せず、公式のPython Dockerイメージをベースにした**コンテナイメージをゼロからビルド**します。
`Dockerfile`と**Dockerキャッシュ**内の命令の**順番**に注意することで、**ビルド時間を最小化**することができ、生産性を最大化することができます(そして退屈を避けることができます)。😎
特別なケースでは、FastAPI用の公式Dockerイメージを使いたいかもしれません。🤓
`Dockerfile`と**Dockerキャッシュ**内の命令の**順番**に注意することで、**ビルド時間を最小化**、生産性を最大化できます(そして退屈を避けることができます)。😎

View File

@@ -1,10 +1,10 @@
# HTTPS について
# HTTPS について { #about-https }
HTTPSは単に「有効」か「無効」かで決まるものだと思いがちです。
しかし、それよりもはるかに複雑です。
/// tip
/// tip | 豆知識
もし急いでいたり、HTTPSの仕組みについて気にしないのであれば、次のセクションに進み、さまざまなテクニックを使ってすべてをセットアップするステップ・バイ・ステップの手順をご覧ください。
@@ -22,25 +22,19 @@ HTTPSは単に「有効」か「無効」かで決まるものだと思いがち
* 接続の暗号化は**TCPレベル**で行われます。
* それは**HTTPの1つ下**のレイヤーです。
* つまり、**証明書と暗号化**の処理は、**HTTPの前**に行われます。
* **TCPは "ドメイン "について知りません**。IPアドレスについてのみ知っています。
* **TCPはドメインについて知りません**。IPアドレスについてのみ知っています。
* 要求された**特定のドメイン**に関する情報は、**HTTPデータ**に入ります。
* **HTTPS証明書**は、**特定のドメイン**を「証明」しますが、プロトコルと暗号化はTCPレベルで行われ、どのドメインが扱われているかを**知る前**に行われます。
* **デフォルトでは**、**IPアドレスごとに1つのHTTPS証明書**しか持てないことになります。
* これは、サーバーの規模やアプリケーションの規模に寄りません。
* しかし、これには**解決策**があります。
* **TLS**プロトコル(HTTPの前に、TCPレベルで暗号化を処理するもの)には、**<a href="https://en.wikipedia.org/wiki/Server_Name_Indication" class="external-link" target="_blank"><abbr title="サーバー名表示">SNI</abbr></a>**と呼ばれる**拡張**があります。
* **TLS**プロトコル(HTTPの前に、TCPレベルで暗号化を処理するもの)には、**<a href="https://en.wikipedia.org/wiki/Server_Name_Indication" class="external-link" target="_blank"><abbr title="Server Name Indication">SNI</abbr></a>**と呼ばれる**拡張**があります。
* このSNI拡張機能により、1つのサーバー**単一のIPアドレス**を持つ)が**複数のHTTPS証明書**を持ち、**複数のHTTPSドメイン/アプリケーション**にサービスを提供できるようになります。
* これが機能するためには、**パブリックIPアドレス**でリッスンしている、サーバー上で動作している**単一の**コンポーネント(プログラム)が、サーバー内の**すべてのHTTPS証明書**を持っている必要があります。
* セキュアな接続を取得した**後**でも、通信プロトコルは**HTTPのまま**です。
* コンテンツは**HTTPプロトコル**で送信されているにもかかわらず、**暗号化**されています。
サーバー(マシン、ホストなど)上で**1つのプログラム/HTTPサーバー**を実行させ、**HTTPSに関する全てのこと**を管理するのが一般的です。
**暗号化された HTTPS リクエスト** を受信し、**復号化された HTTP リクエスト** を同じサーバーで実行されている実際の HTTP アプリケーション(この場合は **FastAPI** アプリケーション)に送信し、アプリケーションから **HTTP レスポンス** を受け取り、適切な **HTTPS 証明書** を使用して **暗号化** し、そして**HTTPS** を使用してクライアントに送り返します。
このサーバーはしばしば **<a href="https://en.wikipedia.org/wiki/TLS_termination_proxy" class="external-link" target="_blank">TLS Termination Proxy</a>**と呼ばれます。
サーバー(マシン、ホストなど)上で**1つのプログラム/HTTPサーバー**を実行させ、**HTTPSに関する全てのこと**を管理するのが一般的です。**暗号化された HTTPS リクエスト** を受信し、**復号化された HTTP リクエスト** を同じサーバーで実行されている実際の HTTP アプリケーション(この場合は **FastAPI** アプリケーション)に送信し、アプリケーションから **HTTP レスポンス** を受け取り、適切な **HTTPS 証明書** を使用して **暗号化** し、そして**HTTPS** を使用してクライアントに送り返します。このサーバーはしばしば **<a href="https://en.wikipedia.org/wiki/TLS_termination_proxy" class="external-link" target="_blank">TLS Termination Proxy</a>**と呼ばれます。
TLS Termination Proxyとして使えるオプションには、以下のようなものがあります
@@ -50,7 +44,7 @@ TLS Termination Proxyとして使えるオプションには、以下のよう
* HAProxy
## Let's Encrypt
## Let's Encrypt { #lets-encrypt }
Let's Encrypt以前は、これらの**HTTPS証明書**は信頼できる第三者によって販売されていました。
@@ -64,27 +58,27 @@ Let's Encrypt以前は、これらの**HTTPS証明書**は信頼できる第三
このアイデアは、これらの証明書の取得と更新を自動化することで、**安全なHTTPSを、無料で、永遠に**利用できるようにすることです。
## 開発者のための HTTPS
## 開発者のための HTTPS { #https-for-developers }
ここでは、HTTPS APIがどのように見えるかの例を、主に開発者にとって重要なアイデアに注意を払いながら、ステップ・バイ・ステップで説明します。
### ドメイン名
### ドメイン名 { #domain-name }
ステップの初めは、**ドメイン名**を**取得すること**から始まるでしょう。その後、DNSサーバーおそらく同じクラウドプロバイダーに設定します。
おそらくクラウドサーバー(仮想マシン)かそれに類するものを手に入れ、<abbr title="変わらない">固定の</abbr> **パブリックIPアドレス**を持つことになるでしょう。
おそらくクラウドサーバー(仮想マシン)かそれに類するものを手に入れ、<abbr title="That doesn't change 変わらない">fixed</abbr> **パブリックIPアドレス**を持つことになるでしょう。
DNSサーバーでは、**取得したドメイン**をあなたのサーバーのパプリック**IPアドレス**に向けるレコード(「`Aレコード`」)を設定します。
DNSサーバーでは、**取得したドメイン**をあなたのサーバーのパプリック**IPアドレス**に向けるレコード(「`A record`」)を設定します。
これはおそらく、最初の1回だけあり、すべてをセットアップするときに行うでしょう。
/// tip
/// tip | 豆知識
ドメイン名の話はHTTPSに関する話のはるか前にありますが、すべてがドメインとIPアドレスに依存するため、ここで言及する価値があります。
///
### DNS
### DNS { #dns }
では、実際のHTTPSの部分に注目してみよう。
@@ -94,7 +88,7 @@ DNSサーバーは、ブラウザに特定の**IPアドレス**を使用する
<img src="/img/deployment/https/https01.drawio.svg">
### TLS Handshake の開始
### TLS Handshake の開始 { #tls-handshake-start }
ブラウザはIPアドレスと**ポート443**HTTPSポートで通信します。
@@ -104,7 +98,7 @@ DNSサーバーは、ブラウザに特定の**IPアドレス**を使用する
TLS接続を確立するためのクライアントとサーバー間のこのやりとりは、**TLSハンドシェイク**と呼ばれます。
### SNI拡張機能付きのTLS
### SNI拡張機能付きのTLS { #tls-with-sni-extension }
サーバー内の**1つのプロセス**だけが、特定 の**IPアドレス**の特定の**ポート** で待ち受けることができます。
@@ -112,7 +106,7 @@ TLS接続を確立するためのクライアントとサーバー間のこの
TLSHTTPSはデフォルトで`443`という特定のポートを使用する。つまり、これが必要なポートです。
このポートをリッスンできるのは1つのプロセスだけなので、これを実行するプロセスは**TLS Termination Proxy**となります。
このポートをリクエストできるのは1つのプロセスだけなので、これを実行するプロセスは**TLS Termination Proxy**となります。
TLS Termination Proxyは、1つ以上の**TLS証明書**HTTPS証明書にアクセスできます。
@@ -130,13 +124,13 @@ TLS Termination Proxyは、1つ以上の**TLS証明書**HTTPS証明書
これが**HTTPS**であり、純粋な暗号化されていないTCP接続ではなく、**セキュアなTLS接続**の中に**HTTP**があるだけです。
/// tip
/// tip | 豆知識
通信の暗号化は、HTTPレベルではなく、**TCPレベル**で行われることに注意してください。
///
### HTTPS リクエスト
### HTTPS リクエスト { #https-request }
これでクライアントとサーバー具体的にはブラウザとTLS Termination Proxyは**暗号化されたTCP接続**を持つことになり、**HTTP通信**を開始することができます。
@@ -144,19 +138,19 @@ TLS Termination Proxyは、1つ以上の**TLS証明書**HTTPS証明書
<img src="/img/deployment/https/https04.drawio.svg">
### リクエストの復号化
### リクエストの復号化 { #decrypt-the-request }
TLS Termination Proxy は、合意が取れている暗号化を使用して、**リクエストを復号化**し、**プレーン (復号化された) HTTP リクエスト** をアプリケーションを実行しているプロセス (例えば、FastAPI アプリケーションを実行している Uvicorn を持つプロセス) に送信します。
<img src="/img/deployment/https/https05.drawio.svg">
### HTTP レスポンス
### HTTP レスポンス { #http-response }
アプリケーションはリクエストを処理し、**プレーン(暗号化されていない)HTTPレスポンス** をTLS Termination Proxyに送信します。
<img src="/img/deployment/https/https06.drawio.svg">
### HTTPS レスポンス
### HTTPS レスポンス { #https-response }
TLS Termination Proxyは次に、事前に合意が取れている暗号(`someapp.example.com`の証明書から始まる)を使って**レスポンスを暗号化し**、ブラウザに送り返す。
@@ -166,7 +160,7 @@ TLS Termination Proxyは次に、事前に合意が取れている暗号(`someap
クライアント(ブラウザ)は、レスポンスが正しいサーバーから来たことを知ることができます。 なぜなら、そのサーバーは、以前に**HTTPS証明書**を使って合意した暗号を使っているからです。
### 複数のアプリケーション
### 複数のアプリケーション { #multiple-applications }
同じサーバーまたは複数のサーバーに、例えば他のAPIプログラムやデータベースなど、**複数のアプリケーション**が存在する可能性があります。
@@ -176,7 +170,7 @@ TLS Termination Proxyは次に、事前に合意が取れている暗号(`someap
そうすれば、TLS Termination Proxy は、**複数のドメイン**や複数のアプリケーションのHTTPSと証明書を処理し、それぞれのケースで適切なアプリケーションにリクエストを送信することができます。
### 証明書の更新
### 証明書の更新 { #certificate-renewal }
将来のある時点で、各証明書は取得後約3ヶ月で**失効**します。
@@ -200,10 +194,42 @@ TLS Termination Proxyは次に、事前に合意が取れている暗号(`someap
アプリを提供しながらこのような更新処理を行うことは、アプリケーション・サーバーUvicornなどでTLS証明書を直接使用するのではなく、TLS Termination Proxyを使用して**HTTPSを処理する別のシステム**を用意したくなる主な理由の1つです。
## まとめ
## プロキシ転送ヘッダー { #proxy-forwarded-headers }
プロキシを使ってHTTPSを処理する場合、**アプリケーションサーバー**たとえばFastAPI CLI経由のUvicornはHTTPS処理について何も知らず、**TLS Termination Proxy**とはプレーンなHTTPで通信します。
この**プロキシ**は通常、リクエストを**アプリケーションサーバー**に転送する前に、その場でいくつかのHTTPヘッダーを設定し、リクエストがプロキシによって**転送**されていることをアプリケーションサーバーに知らせます。
/// note | 技術詳細
プロキシヘッダーは次のとおりです:
* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For" class="external-link" target="_blank">X-Forwarded-For</a>
* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto" class="external-link" target="_blank">X-Forwarded-Proto</a>
* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host" class="external-link" target="_blank">X-Forwarded-Host</a>
///
それでも、**アプリケーションサーバー**は信頼できる**プロキシ**の背後にあることを知らないため、デフォルトではそれらのヘッダーを信頼しません。
しかし、**アプリケーションサーバー**が**プロキシ**から送信される*forwarded*ヘッダーを信頼するように設定できます。FastAPI CLIを使用している場合は、*CLI Option* `--forwarded-allow-ips` を使って、どのIPからの*forwarded*ヘッダーを信頼すべきかを指定できます。
たとえば、**アプリケーションサーバー**が信頼できる**プロキシ**からの通信のみを受け取っている場合、`--forwarded-allow-ips="*"` に設定して、受信するすべてのIPを信頼するようにできます。受け取るリクエストは、**プロキシ**が使用するIPからのものだけになるためです。
こうすることで、アプリケーションは、HTTPSを使用しているかどうか、ドメインなど、自身のパブリックURLが何であるかを把握できるようになります。
これは、たとえばリダイレクトを適切に処理するのに便利です。
/// tip | 豆知識
これについては、[Behind a Proxy - Enable Proxy Forwarded Headers](../advanced/behind-a-proxy.md#enable-proxy-forwarded-headers){.internal-link target=_blank} のドキュメントで詳しく学べます。
///
## まとめ { #recap }
**HTTPS**を持つことは非常に重要であり、ほとんどの場合、かなり**クリティカル**です。開発者として HTTPS に関わる労力のほとんどは、これらの**概念とその仕組みを理解する**ことです。
しかし、ひとたび**開発者向けHTTPS**の基本的な情報を知れば、簡単な方法ですべてを管理するために、さまざまなツールを組み合わせて設定することができます。
次の章では、**FastAPI** アプリケーションのために **HTTPS** をセットアップする方法について、いくつかの具体例を紹介します。🔒
次の章のいくつかでは、**FastAPI** アプリケーションのために **HTTPS** をセットアップする方法について、いくつかの具体例を紹介します。🔒

View File

@@ -1,7 +1,23 @@
# デプロイ
# デプロイ { #deployment }
**FastAPI** 製のアプリケーションは比較的容易にデプロイできます。
**FastAPI** アプリケーションのデプロイは比較的簡単です。
ユースケースや使用しているツールによっていくつかの方法に分かれます。
## デプロイとは { #what-does-deployment-mean }
次のセクションでより詳しくそれらの方法について説明します。
アプリケーションを**デプロイ**するとは、**ユーザーが利用できるようにする**ために必要な手順を実行することを意味します。
**Web API** の場合、通常は **リモートマシン** 上に配置し、優れたパフォーマンス、安定性などを提供する **サーバープログラム** と組み合わせて、**ユーザー** が中断や問題なく効率的にアプリケーションへ**アクセス**できるようにします。
これは **開発** 段階とは対照的です。開発では、コードを常に変更し、壊しては直し、開発サーバーを停止したり再起動したりします。
## デプロイ戦略 { #deployment-strategies }
具体的なユースケースや使用するツールによって、いくつかの方法があります。
複数のツールを組み合わせて自分で**サーバーをデプロイ**することもできますし、作業の一部を代行してくれる **クラウドサービス** を使うこともできます。ほかにも選択肢があります。
たとえば、FastAPI の開発チームである私たちは、クラウドへの FastAPI アプリのデプロイを可能な限り合理化し、FastAPI を使って開発するのと同じ開発者体験を提供するために、<a href="https://fastapicloud.com" class="external-link" target="_blank">**FastAPI Cloud**</a> を構築しました。
**FastAPI** アプリケーションをデプロイする際に、おそらく念頭に置くべき主要な概念をいくつか紹介します(ただし、そのほとんどは他の種類の Web アプリケーションにも当てはまります)。
次のセクションでは、留意すべき点の詳細や、それを実現するためのいくつかの手法を確認します。 ✨

View File

@@ -1,4 +1,4 @@
# Server Workers - Gunicorn と Uvicorn
# Server Workers - ワーカー付きUvicorn { #server-workers-uvicorn-with-workers }
前回のデプロイメントのコンセプトを振り返ってみましょう:
@@ -9,124 +9,79 @@
* メモリ
* 開始前の事前ステップ
ここまでのドキュメントのチュートリアルでは、おそらくUvicornのような**サーバープログラム**を**単一のプロセス**で実行しています。
ここまでのドキュメントのチュートリアルでは、おそらく `fastapi` コマンドなどUvicornを実行するものを使って、**単一のプロセス**として動作する**サーバープログラム**を実行してきたはずです。
アプリケーションをデプロイする際には、**複数のコア**を利用し、そしてより多くのリクエストを処理できるようにするために、プロセスの**レプリケーション**を持つことを望むでしょう。
前のチャプターである[デプロイメントのコンセプト](concepts.md){.internal-link target=_blank}にて見てきたように、有効な戦略がいくつかあります。
ここでは<a href="https://gunicorn.org/" class="external-link" target="_blank">**Gunicorn**</a>が**Uvicornのワーカー・プロセス**を管理する場合の使い方について紹介していきます。
ここでは`fastapi` コマンド、または `uvicorn` コマンドを直接使って、**ワーカープロセス**付きの **Uvicorn** を使う方法を紹介します。
/// info
/// info | 情報
<!-- NOTE: the current version of docker.md is outdated compared to English one. -->
DockerやKubernetesなどのコンテナを使用している場合は、次の章で詳しく説明します [コンテナ内のFastAPI - Docker](docker.md){.internal-link target=_blank}
DockerやKubernetesなどのコンテナを使用している場合は、次の章で詳しく説明します [コンテナ内のFastAPI - Docker](docker.md){.internal-link target=_blank}。
特に**Kubernetes**上で実行する場合は、おそらく**Gunicornを使用せず**、**コンテナごとに単一のUvicornプロセス**を実行することになりますが、それについてはの章の後半で説明します。
特に**Kubernetes**上で実行する場合は、おそらくワーカーは使わず、代わりに**コンテナごとに単一のUvicornプロセス**を実行したいはずですが、それについてはの章の後半で説明します。
///
## GunicornによるUvicornのワーカー・プロセスの管理
## 複数ワーカー { #multiple-workers }
**Gunicorn**は**WSGI標準**のアプリケーションサーバーです。このことは、GunicornはFlaskやDjangoのようなアプリケーションにサービスを提供できることを意味します。Gunicornそれ自体は**FastAPI**と互換性がないですが、というのもFastAPIは最新の**<a href="https://asgi.readthedocs.io/en/latest/" class="external-link" target="_blank">ASGI 標準</a>**を使用しているためです。
`--workers` コマンドラインオプションで複数のワーカーを起動できます。
しかし、Gunicornは**プロセスマネージャー**として動作し、ユーザーが特定の**ワーカー・プロセスクラス**を使用するように指示することができます。するとGunicornはそのクラスを使い1つ以上の**ワーカー・プロセス**を開始します。
//// tab | `fastapi`
そして**Uvicorn**には**Gunicorn互換のワーカークラス**があります。
この組み合わせで、Gunicornは**プロセスマネージャー**として動作し、**ポート**と**IP**をリッスンします。そして、**Uvicornクラス**を実行しているワーカー・プロセスに通信を**転送**します。
そして、Gunicorn互換の**Uvicornワーカー**クラスが、FastAPIが使えるように、Gunicornから送られてきたデータをASGI標準に変換する役割を担います。
## GunicornとUvicornをインストールする
`fastapi` コマンドを使う場合:
<div class="termy">
```console
$ pip install "uvicorn[standard]" gunicorn
$ <font color="#4E9A06">fastapi</font> run --workers 4 <u style="text-decoration-style:solid">main.py</u>
---> 100%
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting production server 🚀
Searching for package file structure from directories with
<font color="#3465A4">__init__.py</font> files
Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
<span style="background-color:#007166"><font color="#D3D7CF"> module </font></span> 🐍 main.py
<span style="background-color:#007166"><font color="#D3D7CF"> code </font></span> Importing the FastAPI app object from the module with the
following code:
<u style="text-decoration-style:solid">from </u><u style="text-decoration-style:solid"><b>main</b></u><u style="text-decoration-style:solid"> import </u><u style="text-decoration-style:solid"><b>app</b></u>
<span style="background-color:#007166"><font color="#D3D7CF"> app </font></span> Using import string: <font color="#3465A4">main:app</font>
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Server started at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font>
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Documentation at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000/docs</u></font>
Logs:
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Uvicorn running on <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font> <b>(</b>Press CTRL+C to
quit<b>)</b>
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started parent process <b>[</b><font color="#34E2E2"><b>27365</b></font><b>]</b>
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>27368</b></font><b>]</b>
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>27369</b></font><b>]</b>
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>27370</b></font><b>]</b>
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>27367</b></font><b>]</b>
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete.
```
</div>
これによりUvicornと高性能を得るための標準`standard`の追加パッケージとGunicornの両方がインストールされます。
////
## UvicornのワーカーとともにGunicornを実行する
//// tab | `uvicorn`
Gunicornを以下のように起動させることができます:
<div class="termy">
```console
$ gunicorn main:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:80
[19499] [INFO] Starting gunicorn 20.1.0
[19499] [INFO] Listening at: http://0.0.0.0:80 (19499)
[19499] [INFO] Using worker: uvicorn.workers.UvicornWorker
[19511] [INFO] Booting worker with pid: 19511
[19513] [INFO] Booting worker with pid: 19513
[19514] [INFO] Booting worker with pid: 19514
[19515] [INFO] Booting worker with pid: 19515
[19511] [INFO] Started server process [19511]
[19511] [INFO] Waiting for application startup.
[19511] [INFO] Application startup complete.
[19513] [INFO] Started server process [19513]
[19513] [INFO] Waiting for application startup.
[19513] [INFO] Application startup complete.
[19514] [INFO] Started server process [19514]
[19514] [INFO] Waiting for application startup.
[19514] [INFO] Application startup complete.
[19515] [INFO] Started server process [19515]
[19515] [INFO] Waiting for application startup.
[19515] [INFO] Application startup complete.
```
</div>
それぞれのオプションの意味を見てみましょう:
* `main:app` `main`は"`main`"という名前のPythonモジュール、つまりファイル`main.py`を意味します。そして `app`**FastAPI** アプリケーションの変数名です。
* main:app`はPythonの`import`文と同じようなものだと想像できます:
```Python
from main import app
```
* つまり、`main:app`のコロンは、`from main import app`のPythonの`import`の部分と同じになります。
* `--workers` 使用するワーカー・プロセスの数で、それぞれがUvicornのワーカーを実行します。
* `--worker-class` ワーカー・プロセスで使用するGunicorn互換のワーカークラスです。
* ここではGunicornがインポートして使用できるクラスを渡します
```Python
import uvicorn.workers.UvicornWorker
```
* `--bind` GunicornにリッスンするIPとポートを伝えます。コロン(`:`)でIPとポートを区切ります。
* Uvicornを直接実行している場合は、`--bind 0.0.0.0:80` Gunicornのオプションの代わりに、`--host 0.0.0.0`と `--port 80`を使います。
出力では、各プロセスの**PID**プロセスIDが表示されているのがわかります単なる数字です
以下の通りです:
* Gunicornの**プロセス・マネージャー**はPID `19499`(あなたの場合は違う番号でしょう)で始まります。
* 次に、`Listening at: http://0.0.0.0:80`を開始します。
* それから `uvicorn.workers.UvicornWorker` でワーカークラスを使用することを検出します。
* そして、**4つのワーカー**を起動します。それぞれのワーカーのPIDは、`19511`、`19513`、`19514`、`19515`です。
Gunicornはまた、ワーカーの数を維持するために必要であれば、**ダウンしたプロセス**を管理し、**新しいプロセスを**再起動**させます。そのため、上記のリストにある**再起動**の概念に一部役立ちます。
しかしながら、必要であればGunicornを**再起動**させ、**起動時に実行**させるなど、外部のコンポーネントを持たせることも必要かもしれません。
## Uvicornとワーカー
Uvicornには複数の**ワーカー・プロセス**を起動し実行するオプションもあります。
とはいうものの、今のところUvicornのワーカー・プロセスを扱う機能はGunicornよりも制限されています。そのため、このレベルPythonレベルでプロセスマネージャーを持ちたいのであれば、Gunicornをプロセスマネージャーとして使ってみた方が賢明かもしれないです。
どんな場合であれ、以下のように実行します:
`uvicorn` コマンドを直接使いたい場合:
<div class="termy">
@@ -150,36 +105,35 @@ $ uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
</div>
ここで唯一の新しいオプションは `--workers` で、Uvicornに4つのワーカー・プロセスを起動するように指示しています。
////
各プロセスの **PID** が表示され、親プロセスの `27365` (これは **プロセスマネージャ**) と、各ワーカープロセスの **PID** が表示されます: `27368`、`27369`、`27370`、`27367`になります。
ここで唯一の新しいオプションは `--workers` で、Uvicornに4つのワーカープロセスを起動するように指示しています。
## デプロイメントのコンセプト
各プロセスの **PID** も表示されていて、親プロセス(これは**プロセスマネージャー**)が `27365`、各ワーカープロセスがそれぞれ `27368``27369``27370``27367` です。
ここでは、アプリケーションの実行を**並列化**し、CPUの**マルチコア**を活用し、**より多くのリクエスト**に対応できるようにするために、**Gunicorn**またはUvicornを使用して**Uvicornワーカー・プロセス**を管理する方法を見ていきました。
## デプロイメントのコンセプト { #deployment-concepts }
上記のデプロイのコンセプトのリストから、ワーカーを使うことは主に**レプリケーション**の部分と、**再起動**を少し助けてくれます:
ここでは、複数の **ワーカー** を使ってアプリケーションの実行を**並列化**し、CPUの**複数コア**を活用して、**より多くのリクエスト**を処理できるようにする方法を見てきました。
* セキュリティ - HTTPS
* 起動時の実行
* 再起動
上のデプロイメントのコンセプトのリストから、ワーカーを使うことは主に**レプリケーション**の部分と、**再起動**を少し助けてくれますが、それ以外については引き続き対処が必要です:
* **セキュリティ - HTTPS**
* **起動時の実行**
* ***再起動***
* レプリケーション(実行中のプロセス数)
* メモリ
* 開始前の事前ステップ
* **メモリ**
* **開始前の事前ステップ**
## コンテナとDocker { #containers-and-docker }
## コンテナとDocker
<!-- NOTE: the current version of docker.md is outdated compared to English one. -->
次章の[コンテナ内のFastAPI - Docker](docker.md){.internal-link target=_blank}では、その他の**デプロイのコンセプト**を扱うために実施するであろう戦略をいくつか紹介します。
次章の[コンテナ内のFastAPI - Docker](docker.md){.internal-link target=_blank}では、その他の**デプロイメントのコンセプト**を扱うために使える戦略をいくつか説明します。
また、**GunicornとUvicornワーカー**を含む**公式Dockerイメージ**と、簡単なケースに役立ついくつかのデフォルト設定も紹介します
単一のUvicornプロセスを実行するために、**ゼロから独自のイメージを構築する**方法も紹介します。これは簡単なプロセスで、**Kubernetes**のような分散コンテナ管理システムを使う場合に、おそらくやりたいことでしょう
また、(Gunicornを使わずに)Uvicornプロセスを1つだけ実行するために、**ゼロから独自のイメージを**構築する方法も紹介します。これは簡単なプロセスで、おそらく**Kubernetes**のような分散コンテナ管理システムを使うときにやりたいことでしょう。
## まとめ { #recap }
## まとめ
`fastapi` または `uvicorn` コマンドで `--workers` CLIオプションを使うことで、**マルチコアCPU**を活用し、**複数のプロセスを並列実行**できるように複数のワーカープロセスを利用できます。
Uvicornワーカーを使ったプロセスマネージャとして**Gunicorn**またはUvicornを使えば、**マルチコアCPU**を活用して**複数のプロセスを並列実行**できます。
他のデプロイメントのコンセプトを自分で対応しながら、**独自のデプロイシステム**を構築している場合にも、これらのツールやアイデアを使えます。
これらのツールやアイデアは、**あなた自身のデプロイシステム**をセットアップしながら、他のデプロイコンセプトを自分で行う場合にも使えます。
次の章では、コンテナDockerやKubernetesなどを使った**FastAPI**について学んでいきましょう。これらのツールには、他の**デプロイのコンセプト**も解決する簡単な方法があることがわかるでしょう。✨
次の章で、コンテナDockerやKubernetesを使った **FastAPI** について学びましょう。これらのツールにも、他の**デプロイメントのコンセプト**を解決する簡単な方法があることがわかります。

View File

@@ -1,93 +1,93 @@
# FastAPIのバージョンについて
# FastAPIのバージョンについて { #about-fastapi-versions }
**FastAPI**に多くのアプリケーションやシステム本番環境使われています。また、100%のテストカバレッジを維持しています。しかし、活発な開発が続いています。
**FastAPI**すでに多くのアプリケーションやシステム本番環境にて使われています。また、テストカバレッジは 100% に維持されています。しかし、開発は依然として急速に進んでいます。
高頻度で新機能が追加され、定期的にバグが修正され、実装は継続的に改善されています。
新機能が高頻度で追加され、定期的にバグが修正され、コードは継続的に改善されています。
これが現在のバージョンがいまだに `0.x.x` な理由であり、それぞれのバージョンは破壊的な変更がなされる可能性があります。これは、<a href="https://semver.org/" class="external-link" target="_blank">セマンティック バージョニング</a>の規則に則っています。
**FastAPI** を使用すると本番用アプリケーションをすぐ作成できますが (すでに何度も経験しているかもしれませんが)、残りのコード正しく動作するバージョンなのか確認しなければいけません
**FastAPI** を使用すると本番用アプリケーションをすぐ作成できます(そして、おそらくあなたはしばらく前からそうしているはずです)。必要なのは、残りのコード正しく動作するバージョンを使用していることを確認することだけです
## `fastapi` のバージョンを固定
## `fastapi` のバージョンを固定 { #pin-your-fastapi-version }
最初にすべきことは、アプリケーションが正しく動作す**FastAPI** のバージョンを固定することです。
最初にすべきことは、使用してい**FastAPI** のバージョンを、アプリケーションで正しく動作することが分かっている特定の最新バージョンに「固定pinすることです。
例えば、バージョン `0.45.0` を使っているとしましょう。
例えば、アプリでバージョン `0.112.0` を使っているとしましょう。
`requirements.txt` を使っているなら、以下のにバージョンを指定できます:
`requirements.txt` ファイルを使う場合は、以下のようにバージョンを指定できます:
```txt
fastapi==0.45.0
fastapi[standard]==0.112.0
```
これは、厳密にバージョン `0.45.0` だけを使うことを意味します。
これは、厳密にバージョン `0.112.0` だけを使うことを意味します。
または、以下のに固定することもできます:
または、以下のように固定することもできます:
```txt
fastapi[standard]>=0.112.0,<0.113.0
```
これは `0.112.0` 以上、`0.113.0` 未満のバージョンを使うことを意味します。例えば、バージョン `0.112.2` は使用可能です。
`uv`、Poetry、Pipenv など、他のインストール管理ツールを使用している場合でも、いずれもパッケージの特定バージョンを定義する方法があります。
## 利用可能なバージョン { #available-versions }
利用可能なバージョン(例: 現在の最新が何かを確認するため)は、[Release Notes](../release-notes.md){.internal-link target=_blank} で確認できます。
## バージョンについて { #about-versions }
セマンティック バージョニングの規約に従って、`1.0.0` 未満のバージョンは破壊的な変更が加わる可能性があります。
FastAPI では「PATCH」バージョンの変更はバグ修正と非破壊的な変更に使う、という規約にも従っています。
/// tip | 豆知識
「PATCH」は最後の数字です。例えば、`0.2.3` では PATCH バージョンは `3` です。
///
従って、以下のようなバージョンの固定ができるはずです:
```txt
fastapi>=0.45.0,<0.46.0
```
これは `0.45.0` 以上、`0.46.0` 未満のバージョンを使うことを意味します。例えば、バージョン `0.45.2` は使用可能です。
PoetryやPipenvなど、他のインストール管理ツールを使用している場合でも、それぞれパッケージのバージョンを指定する機能があります。
## 利用可能なバージョン
[Release Notes](../release-notes.md){.internal-link target=_blank}で利用可能なバージョンが確認できます (現在の最新版の確認などのため)。
## バージョンについて
セマンティック バージョニングの規約に従って、`1.0.0` 未満の全てのバージョンは破壊的な変更が加わる可能性があります。
FastAPIでは「パッチ」バージョンはバグ修正と非破壊的な変更に留めるという規約に従っています。
破壊的な変更と新機能は「MINOR」バージョンで追加されます。
/// tip | 豆知識
パッチ」は最後の数字を指します。例えば、`0.2.3` ではパッチバージョンは `3` です。
MINOR」は真ん中の数字です。例えば、`0.2.3` では MINOR バージョンは `2` です。
///
従って、以下の様なバージョンの固定が望ましいです:
## FastAPIのバージョンのアップグレード { #upgrading-the-fastapi-versions }
```txt
fastapi>=0.45.0,<0.46.0
```
アプリケーションにテストを追加すべきです。
破壊的な変更と新機能実装は「マイナー」バージョンで加えられます。
**FastAPI** では非常に簡単に実現できますStarlette のおかげです)。ドキュメントを確認して下さい: [テスト](../tutorial/testing.md){.internal-link target=_blank}
/// tip | 豆知識
テストを追加したら、**FastAPI** のバージョンをより新しいものにアップグレードし、テストを実行することで全てのコードが正しく動作するか確認できます。
「マイナー」は真ん中の数字です。例えば、`0.2.3` ではマイナーバージョン `2`す。
全てが動作する、または必要な変更を行った後に全てのテストが通るなら、その新しいバージョン `fastapi` を固定できます。
///
## Starletteについて { #about-starlette }
## FastAPIのバージョンのアップグレード
`starlette` のバージョンは固定すべきではありません。
アプリケーションにテストを加えるべきです。
**FastAPI** のバージョンが異なれば、Starlette の特定のより新しいバージョンが使われます。
**FastAPI** では非常に簡単に実現できます (Starletteのおかげで)。ドキュメントを確認して下さい: [テスト](../tutorial/testing.md){.internal-link target=_blank}
そのため、正しい Starlette バージョンを **FastAPI** に任せればよいです。
テストを加えた後で、**FastAPI** のバージョンをより最新のものにアップグレードし、テストを実行することで全てのコードが正常に動作するか確認できます。
## Pydanticについて { #about-pydantic }
全てが動作するか、修正を行った上で全てのテストを通過した場合、使用している`fastapi` のバージョンをより最新のバージョンに固定できます。
Pydantic は自身のテストに **FastAPI** のテストも含んでいるため、Pydantic の新しいバージョン(`1.0.0` より上)は常に FastAPI と互換性があります。
## Starletteについて
`Starlette` のバージョンは固定すべきではありません。
**FastAPI** は、バージョン毎にStarletteのより新しいバージョンを使用します。
よって、最適なStarletteのバージョン選択を**FastAPI** に任せることができます。
## Pydanticについて
Pydanticは自身のテストだけでなく**FastAPI** のためのテストを含んでいます。なので、Pydanticの新たなバージョン ( `1.0.0` 以降) は全てFastAPIと整合性があります。
Pydanticのバージョンを、動作が保証できる`1.0.0`以降のいずれかのバージョンから`2.0.0` 未満の間に固定できます。
Pydantic は、自分にとって動作する `1.0.0` より上の任意のバージョンに固定できます。
例えば:
```txt
pydantic>=1.2.0,<2.0.0
pydantic>=2.7.0,<3.0.0
```

View File

@@ -1,18 +1,18 @@
# 環境変数
# 環境変数 { #environment-variables }
/// tip
/// tip | 豆知識
もし、「環境変数」とは何か、それをどう使うかを既に知っている場合は、このセクションをスキップして構いません。
///
環境変数(**env var**とも呼ばれる)はPythonコードの**外側**、つまり**OS**に存在する変数で、Pythonから読み取ることができます。(他のプログラムでも同様に読み取れます。
環境変数(**env var**とも呼ばれます)とは、Pythonコードの**外側**、つまり**オペレーティングシステム**に存在する変数で、Pythonコード(または他のプログラム)から読み取れます。
環境変数は、アプリケーションの**設定**の管理や、Pythonの**インストール**など役立ちます。
環境変数は、アプリケーションの**設定**の扱い、Pythonの**インストール**の一部など役立ちます。
## 環境変数の作成と使用
## 環境変数の作成と使用 { #create-and-use-env-vars }
環境変数は**シェル(ターミナル)**で**作成**して使用でき、それらにPythonは不要です。
環境変数は、Pythonを必要とせず、**シェル(ターミナル)**で**作成**して使用できす。
//// tab | Linux, macOS, Windows Bash
@@ -36,7 +36,6 @@ Hello Wade Wilson
<div class="termy">
```console
// Create an env var MY_NAME
$ $Env:MY_NAME = "Wade Wilson"
@@ -51,9 +50,9 @@ Hello Wade Wilson
////
## Pythonで環境変数を読み取る
## Pythonで環境変数を読み取る { #read-env-vars-in-python }
環境変数Pythonの**外側**ターミナル(や他の方法)で作成し、**Pythonで読み取る**こともできます。
環境変数Pythonの**外側**ターミナル、またはその他の方法)で作成し、その後に**Pythonで読み取る**こともできます。
例えば、以下のような`main.py`ファイルを用意します:
@@ -64,11 +63,11 @@ name = os.getenv("MY_NAME", "World")
print(f"Hello {name} from Python")
```
/// tip
/// tip | 豆知識
<a href="https://docs.python.org/3.8/library/os.html#os.getenv" class="external-link" target="_blank">`os.getenv()`</a> の第2引数は、デフォルトで返される値を指定します。
<a href="https://docs.python.org/3.8/library/os.html#os.getenv" class="external-link" target="_blank">`os.getenv()`</a> の第2引数は、デフォルトで返される値す。
この引数を省略するとデフォルト値として`None`が返されますが、ここではデフォルト値として`"World"`を指定しています。
指定しない場合、デフォルト`None`すが、ここでは使用するデフォルト値として`"World"`を指定しています。
///
@@ -128,11 +127,11 @@ Hello Wade Wilson from Python
////
環境変数はコードの外側で設定し、内側から読み取ることができるので、他のファイルと一緒に(`git`に)保存する必要がありません。そのため、環境変数をコンフィグレーションや**設定**に使用することが一般的です。
環境変数はコードの外側で設定でき、コードから読み取れ、他のファイルと一緒に(`git`に)保存(コミット)する必要がないため、設定や**settings**に使うのが一般的です。
また、**特定のプログラムの呼び出し**のための環境変数を、そのプログラムのみ、その実行中に限定して利用できるよう作成できます。
また、**特定のプログラムの呼び出し**のためだけに、そのプログラムのみ、実行中の間だけ利用できる環境変数を作成することもできます。
そのためには、プログラム起動コマンドと同じコマンドライン上の、起動コマンド直前で環境変数を作成してください。
そのためには、同じ行で、プログラム自体の直前に作成してください。
<div class="termy">
@@ -152,25 +151,25 @@ Hello World from Python
</div>
/// tip
/// tip | 豆知識
詳しくは <a href="https://12factor.net/config" class="external-link" target="_blank">The Twelve-Factor App: Config</a> を参照してください。
///
## 型とバリデーション
## 型とバリデーション { #types-and-validation }
環境変数は**テキスト文字列**のみを扱うことができます。これは、環境変数Python外部に存在し、他のプログラムやシステム全体Linux、Windows、macOS間の互換性を含む)と連携する必要があるためです。
これらの環境変数が扱えるのは**テキスト文字列**のみです。環境変数Python外部にあり、他のプログラムやシステム全体Linux、Windows、macOSなど異なるオペレーティングシステム間も)との互換性が必要になるためです。
つまり、Pythonが環境変数から読み取る**あらゆる値**は **`str`型となり**、他の型への変換やバリデーションはコード内で行う必要があります。
つまり、環境変数からPythonで読み取る**あらゆる値**は **`str`なり**、他の型への変換やバリデーションはコード内で行う必要があります。
環境変数を使用して**アプリケーション設定**を管理する方法については、[高度なユーザーガイド - Settings and Environment Variables](./advanced/settings.md){.internal-link target=_blank}で詳しく学べます。
環境変数を使て**アプリケーション設定**を扱う方法については、[高度なユーザーガイド - Settings and Environment Variables](./advanced/settings.md){.internal-link target=_blank} で詳しく学べます。
## `PATH`環境変数
## `PATH`環境変数 { #path-environment-variable }
**`PATH`**という**特別な**環境変数があります。この環境変数は、OSLinux、macOS、Windowsが実行するプログラムを発見するために使用されます。
**`PATH`**という**特別な**環境変数があります。これはオペレーティングシステムLinux、macOS、Windowsが実行するプログラムを見つけるために使用されます。
`PATH`変数は、複数のディレクトリのパスから成る長い文字列です。このパスはLinuxやMacOSの場合は`:`、Windowsの場合は`;`で区切られています。
変数`PATH`の値は長い文字列で、LinuxとmacOSではコロン`:`、Windowsではセミコロン`;`で区切られたディレクトリで構成されます。
例えば、`PATH`環境変数は次のような文字列かもしれません:
@@ -180,7 +179,7 @@ Hello World from Python
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
```
これは、OSはプログラムを見つけるために以下のディレクトリを探す、ということを意味します:
これは、システムが次のディレクトリでプログラムを探すことを意味します:
* `/usr/local/bin`
* `/usr/bin`
@@ -196,7 +195,7 @@ Hello World from Python
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32
```
これは、OSはプログラムを見つけるために以下のディレクトリを探す、ということを意味します:
これは、システムが次のディレクトリでプログラムを探すことを意味します:
* `C:\Program Files\Python312\Scripts`
* `C:\Program Files\Python312`
@@ -204,63 +203,61 @@ C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System3
////
ターミナル上で**コマンド**を入力すると、 OSはそのプログラムを見つけるために、`PATH`環境変数のリストに記載された**それぞれのディレクトリ探し**ます。
ターミナル上で**コマンド**を入力すると、オペレーティングシステムは`PATH`環境変数に記載された**それぞれのディレクトリ**の中からプログラムを**探し**ます。
例えば、ターミナルで`python`入力すると、OSは`python`によって呼ばれるプログラムを見つけるために、そのリストの**先頭のディレクトリ**を最初に探します。
例えば、ターミナルで`python`入力すると、オペレーティングシステムはそのリストの**最初のディレクトリ**で`python`というプログラムを探します。
OSは、もしそのプログラムをそこで発見すれば**実行し**ますが、そうでなければリストの**他のディレクトリ**を探していきます。
見つかればそれを**使用**ます。見つからなければ、**他のディレクトリ**を探し続けます。
### PythonのインストールとPATH環境変数の更新
### Pythonのインストールと`PATH`の更新 { #installing-python-and-updating-the-path }
Pythonのインストール時に`PATH`環境変数を更新したいか聞かれるかもしれません。
Pythonのインストール時に`PATH`環境変数を更新するかどうかを尋ねられるかもしれません。
/// tab | Linux, macOS
//// tab | Linux, macOS
Pythonをインストールして、そのプログラムが`/opt/custompython/bin`というディレクトリに配置されたとします。
Pythonをインストールして、その結果`/opt/custompython/bin`というディレクトリに配置されたとします。
もし、`PATH`環境変数を更新するように答えると、`PATH`環境変数に`/opt/custompython/bin`追加されます。
`PATH`環境変数を更新することに同意すると、インストーラーは`PATH`環境変数に`/opt/custompython/bin`追加ます。
`PATH`環境変数は以下のように更新されるでしょう:
例えば次のようになります:
``` plaintext
```plaintext
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/custompython/bin
```
このようにして、ターミナルで`python`と入力したときに、OSは`/opt/custompython/bin`リストの末尾のディレクトリにあるPythonプログラムを見つけ、使用します。
このようにして、ターミナルで`python`と入力すると、システムは`/opt/custompython/bin`最後のディレクトリにあるPythonプログラムを見つけ、それを使用します。
///
////
/// tab | Windows
//// tab | Windows
Pythonをインストールして、そのプログラムが`C:\opt\custompython\bin`というディレクトリに配置されたとします。
Pythonをインストールして、その結果`C:\opt\custompython\bin`というディレクトリに配置されたとします。
もし、`PATH`環境変数を更新するように答えると、`PATH`環境変数に`C:\opt\custompython\bin`追加されます。
`PATH`環境変数は以下のように更新されるでしょう:
`PATH`環境変数を更新することに同意すると、インストーラーは`PATH`環境変数に`C:\opt\custompython\bin`追加ます。
```plaintext
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin
```
このようにして、ターミナルで`python`と入力したときに、OSは`C:\opt\custompython\bin\python`(リストの末尾のディレクトリにあるPythonプログラムを見つけ、使用します。
このようにして、ターミナルで`python`と入力すると、システムは`C:\opt\custompython\bin`(最後のディレクトリにあるPythonプログラムを見つけ、それを使用します。
///
////
つまり、ターミナルで以下のコマンドを入力すると
つまり、ターミナルで次のように入力すると:
<div class="termy">
``` console
```console
$ python
```
</div>
/// tab | Linux, macOS
//// tab | Linux, macOS
OSは`/opt/custompython/bin`にある`python`プログラムを**見つけ**て実行します。
システムは`/opt/custompython/bin`にある`python`プログラムを**見つけ**て実行します。
これは、次のコマンドを入力した場合とほとんど同等です
これは、次のように入力するのとおおむね同等です:
<div class="termy">
@@ -270,13 +267,13 @@ $ /opt/custompython/bin/python
</div>
///
////
/// tab | Windows
//// tab | Windows
OSは`C:\opt\custompython\bin\python`にある`python`プログラムを**見つけ**て実行します。
システムは`C:\opt\custompython\bin\python`にある`python`プログラムを**見つけ**て実行します。
これは、次のコマンドを入力した場合とほとんど同等です
これは、次のように入力するのとおおむね同等です:
<div class="termy">
@@ -286,16 +283,16 @@ $ C:\opt\custompython\bin\python
</div>
///
////
この情報は、[Virtual Environments](virtual-environments.md) について学ぶ際にも役立ちます。
この情報は、[Virtual Environments](virtual-environments.md){.internal-link target=_blank} について学ぶ際にも役立ちます。
## まとめ
## まとめ { #conclusion }
これで、**環境変数**とは何か、Pythonでどのように使用するかについて、基本的な理解が得られたはずです。
環境変数についての詳細は、<a href="https://en.wikipedia.org/wiki/Environment_variable" class="external-link" target="_blank">Wikipedia: Environment Variable</a> 参照してください。
環境変数についての詳細は、<a href="https://en.wikipedia.org/wiki/Environment_variable" class="external-link" target="_blank">Wikipedia for Environment Variable</a> 参照してください。
環境変数の用途や適用方法が最初は直感的ではないかもしれませんが、開発中のさまざまなシナリオで繰り返し登場します。そのため、基本を知っておくことが重要です
多くの場合、環境変数がどのように役立ち、すぐに適用できるのかはあまり明確ではありません。しかし、開発中のさまざまなシナリオで何度も登場するため、知っておくとよいでしょう
たとえば、この情報は次のセクションで扱う[Virtual Environments](virtual-environments.md)にも関連します。
えば、次のセクション[Virtual Environments](virtual-environments.md)でこの情報が必要になります。

View File

@@ -1,8 +1,8 @@
# 条件付き OpenAPI
# 条件付き OpenAPI { #conditional-openapi }
必要であれば、設定と環境変数を利用して、環境に応じて条件付きでOpenAPIを構成することが可能です。また、完全にOpenAPIを無効にすることもできます。
## セキュリティとAPI、およびドキュメントについて
## セキュリティとAPI、およびドキュメントについて { #about-security-apis-and-docs }
本番環境においてドキュメントのUIを非表示にすることによって、APIを保護しようと *すべきではありません*
@@ -17,19 +17,19 @@
* リクエストボディとレスポンスのためのPydanticモデルの定義を見直す。
* 依存関係に基づきすべての必要なパーミッションとロールを設定する。
* パスワードを絶対に平文で保存しない。パスワードハッシュのみを保存する。
* PasslibやJWTトークンに代表される、よく知られた暗号化ツールを使って実装する。
* pwdlibやJWTトークンに代表される、よく知られた暗号化ツールを使って実装する。
* そして必要なところでは、もっと細かいパーミッション制御をOAuth2スコープを使って行う。
* など
* ...など
それでも、例えば本番環境のような特定の環境のみで、あるいは環境変数の設定によってAPIドキュメントをどうしても無効にしたいという、非常に特殊なユースケースがあるかもしれません。
## 設定と環境変数による条件付き OpenAPI
## 設定と環境変数による条件付き OpenAPI { #conditional-openapi-from-settings-and-env-vars }
生成するOpenAPIとドキュメントUIの構成は、共通のPydanticの設定を使用して簡単に切り替えられます。
例えば、
{* ../../docs_src/conditional_openapi/tutorial001.py hl[6,11] *}
{* ../../docs_src/conditional_openapi/tutorial001_py39.py hl[6,11] *}
ここでは `openapi_url` の設定を、デフォルトの `"/openapi.json"` のまま宣言しています。

View File

@@ -1,14 +1,14 @@
# FastAPI
# FastAPI { #fastapi }
<style>
.md-content .md-typeset h1 { display: none; }
</style>
<p align="center">
<a href="https://fastapi.tiangolo.com"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" alt="FastAPI"></a>
<a href="https://fastapi.tiangolo.com/ja"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" alt="FastAPI"></a>
</p>
<p align="center">
<em>FastAPI framework, high performance, easy to learn, fast to code, ready for production</em>
<em>FastAPI フレームワーク、高パフォーマンス、学びやすい、素早くコーディングできる、本番運用に対応</em>
</p>
<p align="center">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
@@ -27,129 +27,138 @@
---
**ドキュメント**: <a href="https://fastapi.tiangolo.com" target="_blank">https://fastapi.tiangolo.com</a>
**ドキュメント**: <a href="https://fastapi.tiangolo.com/ja" target="_blank">https://fastapi.tiangolo.com</a>
**ソースコード**: <a href="https://github.com/fastapi/fastapi" target="_blank">https://github.com/fastapi/fastapi</a>
---
FastAPI は、Pythonの標準である型ヒントに基づいてPython 以降でAPI を構築するための、モダンで、高速(高パフォーマンス)な、Web フレームワークです。
FastAPI は、Python の標準である型ヒントに基づいて Python で API を構築するための、モダンで、高速高パフォーマンス)な Web フレームワークです。
主な特徴:
- **高速**: **NodeJS****Go** 並みのとても高いパフォーマンス (Starlette と Pydantic のおかげです)。 [最も高速な Python フレームワークの一つです](#_10).
* **高速**: **NodeJS****Go** 並みのとても高いパフォーマンスStarlette と Pydantic のおかげです。 [利用可能な最も高速な Python フレームワークの一つです](#performance)
* **高速なコーディング**: 開発速度を約 200%〜300% 向上させます。*
* **少ないバグ**: 開発者起因のヒューマンエラーを約 40% 削減します。*
* **直感的**: 素晴らしいエディタサポート。あらゆる場所で <abbr title="also known as auto-complete, autocompletion, IntelliSense">補完</abbr> が使えます。デバッグ時間を削減します。
* **簡単**: 簡単に利用・習得できるようにデザインされています。ドキュメントを読む時間を削減します。
* **短い**: コードの重複を最小限にします。各パラメータ宣言から複数の機能を得られます。バグも減ります。
* **堅牢性**: 自動対話型ドキュメントにより、本番環境向けのコードが得られます。
* **Standards-based**: API のオープンスタンダードに基づいており(そして完全に互換性があります)、<a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a>(以前は Swagger として知られていました)や <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a> をサポートします。
- **高速なコーディング**: 開発速度を約 200%~300%向上させます。 \*
- **少ないバグ**: 開発者起因のヒューマンエラーを約 40削減します。 \*
- **直感的**: 素晴らしいエディタのサポートや <abbr title="also known as auto-complete, autocompletion, IntelliSense">オートコンプリート。</abbr> デバッグ時間を削減します。
- **簡単**: 簡単に利用、習得できるようにデザインされています。ドキュメントを読む時間を削減します。
- **短い**: コードの重複を最小限にしています。各パラメータからの複数の機能。少ないバグ。
- **堅牢性**: 自動対話ドキュメントを使用して、本番環境で使用できるコードを取得します。
- **Standards-based**: API のオープンスタンダードに基づいており、完全に互換性があります: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (以前は Swagger として知られていました) や <a href="https://json-schema.org/" class="external-link" target="_blank">JSON スキーマ</a>.
<small>* 本番アプリケーションを構築している社内開発チームのテストに基づく見積もりです。</small>
<small>\* 本番アプリケーションを構築している開発チームのテストによる見積もり。</small>
## Sponsors
## Sponsors { #sponsors }
<!-- sponsors -->
{% if sponsors %}
### Keystone Sponsor { #keystone-sponsor }
{% for sponsor in sponsors.keystone -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor -%}
### Gold and Silver Sponsors { #gold-and-silver-sponsors }
{% for sponsor in sponsors.gold -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor -%}
{%- for sponsor in sponsors.silver -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor %}
{% endif %}
<!-- /sponsors -->
<a href="https://fastapi.tiangolo.com/fastapi-people/#sponsors" class="external-link" target="_blank">Other sponsors</a>
<a href="https://fastapi.tiangolo.com/ja/fastapi-people/#sponsors" class="external-link" target="_blank">その他のスポンサー</a>
## 評価
## 評価 { #opinions }
"_[...] 最近 **FastAPI** を使っています。 [...] 実際に私のチームの全ての **Microsoft の機械学習サービス** で使用する予定です。 そのうちのいくつかのコアな**Windows**製品と**Office**製品に統合されつつあります。_"
"_[...] 最近 **FastAPI** を使っています。 [...] 実際に私のチームの全ての **Microsoft の機械学習サービス** で使用する予定です。 そのうちのいくつかのコアな **Windows** 製品と **Office** 製品に統合されつつあります。_"
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div>
---
"_FastAPIライブラリを採用し、クエリで**予測値**を取得できる**REST**サーバを構築しました。 [for Ludwig]_"
"_FastAPIライブラリを採用し、クエリで **予測値** を取得できる **REST** サーバを構築しました。 [for Ludwig]_"
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div>
---
"_**Netflix** は、**危機管理**オーケストレーションフレームワーク、**Dispatch**のオープンソースリリースを発表できることをうれしく思います。 [built with **FastAPI**]_"
"_**Netflix** は、**危機管理**オーケストレーションフレームワーク、**Dispatch** のオープンソースリリースを発表できることをうれしく思います。 [built with **FastAPI**]_"
<div style="text-align: right; margin-right: 10%;">Kevin Glisson, Marc Vilanova, Forest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072" target="_blank"><small>(ref)</small></a></div>
---
"_私は**FastAPI**にワクワクしています。 めちゃくちゃ楽しいです_"
"_私は **FastAPI** にワクワクしています。 めちゃくちゃ楽しいです_"
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a> podcast host</strong> <a href="https://x.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
---
"_正直、超堅実で洗練されているように見えます。いろんな意味で、それは私がハグしたかったものです。_"
"_正直、あなたが作ったものは超堅実で洗練されているように見えます。いろんな意味で、それは私が **Hug** にそうなってほしかったものです。誰かがそれを作るのを見るのは本当に刺激的です。_"
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
---
"_REST API を構築するための**モダンなフレームワーク**を学びたい方は、**FastAPI** [...] をチェックしてみてください。 [...] 高速で, 使用習得が簡単です[...]_"
"_REST API を構築するための **モダンなフレームワーク** を学びたい方は、**FastAPI** [...] をチェックしてみてください。 [...] 高速で使用習得が簡単です [...]_"
"_私たちの**API**は**FastAPI**に切り替えました[...] きっと気に入ると思います [...]_"
"_私たちの **API****FastAPI** に切り替えました [...] きっと気に入ると思います [...]_"
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> founders - <a href="https://spacy.io" target="_blank">spaCy</a> creators</strong> <a href="https://x.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://x.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
---
## **Typer**, the FastAPI of CLIs
"_本番運用の Python API を構築したい方には、**FastAPI** を強くおすすめします。**美しく設計**されており、**使いやすく**、**高いスケーラビリティ**があります。私たちの API ファースト開発戦略の **主要コンポーネント** となり、Virtual TAC Engineer などの多くの自動化やサービスを推進しています。_"
<div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/" target="_blank"><small>(ref)</small></a></div>
---
## FastAPI ミニドキュメンタリー { #fastapi-mini-documentary }
2025 年末に公開された <a href="https://www.youtube.com/watch?v=mpR8ngthqiE" class="external-link" target="_blank">FastAPI ミニドキュメンタリー</a>があります。オンラインで視聴できます:
<a href="https://www.youtube.com/watch?v=mpR8ngthqiE" target="_blank"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini Documentary"></a>
## **Typer**、CLI 版 FastAPI { #typer-the-fastapi-of-clis }
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
もし Web API の代わりにターミナルで使用する<abbr title="Command Line Interface">CLI</abbr>アプリを構築する場合は、<a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>を確認してください。
Web API の代わりにターミナルで使用する <abbr title="Command Line Interface">CLI</abbr> アプリを構築する場合は、<a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a> を確認してください。
**Typer**は FastAPI の弟分です。そして、**CLI 版 FastAPI**を意しています。
**Typer** は FastAPI の弟分です。そして、**CLI 版 FastAPI** を意しています。 ⌨️ 🚀
## 必要条件
## 必要条件 { #requirements }
FastAPI は巨人の肩の上に立っています。
- Web の部分は<a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a>
- データの部分は<a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a>
* Web の部分は <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a>
* データの部分は <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a>
## インストール
## インストール { #installation }
<a href="https://fastapi.tiangolo.com/ja/virtual-environments/" class="external-link" target="_blank">virtual environment</a> を作成して有効化し、それから FastAPI をインストールします。
<div class="termy">
```console
$ pip install fastapi
$ pip install "fastapi[standard]"
---> 100%
```
</div>
本番環境では、<a href="https://www.uvicorn.dev" class="external-link" target="_blank">Uvicorn</a> または、 <a href="https://github.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>のような、 ASGI サーバーが必要になります
**注**: すべてのターミナルで動作するように、`"fastapi[standard]"` は必ずクォートで囲んでください
<div class="termy">
## アプリケーション例 { #example }
```console
$ pip install "uvicorn[standard]"
### 作成 { #create-it }
---> 100%
```
</div>
## アプリケーション例
### アプリケーションの作成
- `main.py` を作成し、以下のコードを入力します:
`main.py` ファイルを作成し、以下のコードを入力します。
```Python
from fastapi import FastAPI
@@ -163,16 +172,16 @@ def read_root():
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
def read_item(item_id: int, q: str | None = None):
return {"item_id": item_id, "q": q}
```
<details markdown="1">
<summary>または<code>async def</code>を使います...</summary>
<summary>または <code>async def</code> を使います...</summary>
`async` / `await`を使用するときは、 `async def`を使います:
コードで `async` / `await` を使用する場合は、`async def` を使います
```Python hl_lines="7 12"
```Python hl_lines="7 12"
from fastapi import FastAPI
app = FastAPI()
@@ -184,28 +193,41 @@ async def read_root():
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str = None):
async def read_item(item_id: int, q: str | None = None):
return {"item_id": item_id, "q": q}
```
**注**:
わからない場合は、<a href="https://fastapi.tiangolo.com/async/#in-a-hurry" target="_blank">ドキュメントの`async` と `await`にある</a>"In a hurry?"セクションをチェックしてください。
わからない場合は、<a href="https://fastapi.tiangolo.com/ja/async/#in-a-hurry" target="_blank">ドキュメントの `async` と `await` の _"In a hurry?"_ セクション</a>を確認してください。
</details>
### 実行
### 実行 { #run-it }
以下のコマンドでサーバーを起動します:
以下のコマンドでサーバーを起動します
<div class="termy">
```console
$ uvicorn main:app --reload
$ fastapi dev main.py
╭────────── FastAPI CLI - Development mode ───────────╮
│ │
│ Serving at: http://127.0.0.1:8000 │
│ │
│ API docs: http://127.0.0.1:8000/docs │
│ │
│ Running in development mode, for production use: │
│ │
│ fastapi run │
│ │
╰─────────────────────────────────────────────────────╯
INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp']
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [28720]
INFO: Started server process [28722]
INFO: Started reloader process [2248755] using WatchFiles
INFO: Started server process [2248757]
INFO: Waiting for application startup.
INFO: Application startup complete.
```
@@ -213,56 +235,56 @@ INFO: Application startup complete.
</div>
<details markdown="1">
<summary><code>uvicorn main:app --reload</code>コマンドについて</summary>
<summary><code>fastapi dev main.py</code> コマンドについて</summary>
`uvicorn main:app`コマンドは以下の項目を参照します:
`fastapi dev` コマンドは `main.py` ファイルを読み取り、その中の **FastAPI** アプリを検出し、<a href="https://www.uvicorn.dev" class="external-link" target="_blank">Uvicorn</a> を使用してサーバーを起動します
- `main`: `main.py`ファイル (Python "モジュール")
- `app`: `main.py` の`app = FastAPI()`の行で生成されたオブジェクト
- `--reload`: コードを変更したらサーバーを再起動します。このオプションは開発環境でのみ使用します
デフォルトでは、`fastapi dev` はローカル開発向けに自動リロードを有効にして起動します。
詳しくは <a href="https://fastapi.tiangolo.com/ja/fastapi-cli/" target="_blank">FastAPI CLI docs</a> を参照してください。
</details>
### 動作確認
### 動作確認 { #check-it }
ブラウザから<a href="http://127.0.0.1:8000/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1:8000/items/5?q=somequery</a>を開きます。
ブラウザ<a href="http://127.0.0.1:8000/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1:8000/items/5?q=somequery</a> を開きます。
以下の JSON のレスポンスが確認できます:
以下の JSON のレスポンスが確認できます
```JSON
{"item_id": 5, "q": "somequery"}
```
もうすでに以下の API が作成されています:
すでに以下の API が作成されています
- `/` と `/items/{item_id}`のパスで HTTP リクエストを受けます。
- どちらのパスも `GET` <em>操作</em> を取ります。(HTTP メソッドとしても知られています。)
- `/items/{item_id}` パスのパスパラメータ `item_id` は `int` でなければなりません
- パス `/items/{item_id}` はオプションの `str` クエリパラメータ `q` を持ちます。
* _パス_ `/` と `/items/{item_id}` で HTTP リクエストを受け取ります。
* 両方の _パス_ は `GET` <em>操作</em>HTTP _メソッド_ としても知られています)を取ります
* _パス_ `/items/{item_id}` は `int` であるべき _パスパラメータ_ `item_id` を持ちます
* _パス_ `/items/{item_id}` はオプションの `str` _クエリパラメータ_ `q` を持ちます。
### 自動対話型 API ドキュメント
### 自動対話型 API ドキュメント { #interactive-api-docs }
<a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>にアクセスしてみてください
次に、<a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> にアクセスします
自動対話型 API ドキュメントが表示されます。 (<a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>が提供しています。):
自動対話型 API ドキュメントが表示されます<a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a> が提供しています
![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
### 代替 API ドキュメント
### 代替 API ドキュメント { #alternative-api-docs }
<a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>にアクセスしてみてください
次に、<a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> にアクセスします
代替の自動ドキュメントが表示されます。(<a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>が提供しています。):
代替の自動ドキュメントが表示されます<a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a> が提供しています
![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
## アップグレード例
## アップグレード例 { #example-upgrade }
`PUT`リクエストからボディを受け取るために`main.py`を修正しましょう。
次に、`PUT` リクエストからボディを受け取るために `main.py` ファイルを修正しましょう。
Pydantic によって、Python の標準的な型を使ってボディを宣言します。
Pydantic によって、標準的な Python の型を使ってボディを宣言します。
```Python hl_lines="2 7 8 9 10 23 24 25"
```Python hl_lines="2 7-10 23-25"
from fastapi import FastAPI
from pydantic import BaseModel
@@ -272,7 +294,7 @@ app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: bool = None
is_offer: bool | None = None
@app.get("/")
@@ -281,7 +303,7 @@ def read_root():
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
def read_item(item_id: int, q: str | None = None):
return {"item_id": item_id, "q": q}
@@ -290,173 +312,248 @@ def update_item(item_id: int, item: Item):
return {"item_name": item.name, "item_id": item_id}
```
サーバーは自動でリロードされます。(上述の`uvicorn`コマンドで`--reload`オプションを追加しているからです。)
`fastapi dev` サーバーは自動でリロードされるはずです。
### 自動対話型 API ドキュメントのアップグレード
### 自動対話型 API ドキュメントのアップグレード { #interactive-api-docs-upgrade }
<a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>にアクセスしましょう
次に、<a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> にアクセスしま
- 自動対話型 API ドキュメント新しいボディも含めて自動でアップデートされます:
* 自動対話型 API ドキュメント新しいボディも含めて自動でアップデートされます
![Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png)
- "Try it out"ボタンをクリックしてください。パラメータを入力して API と直接やりとりすることができます:
* 「Try it outボタンをクリックします。パラメータを入力して API と直接やりとりできます
![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-04-swagger-03.png)
- それから、"Execute" ボタンをクリックしてください。 ユーザーインターフェースは API と通信し、パラメータを送信し、結果を取得して画面に表示します:
* 次に、「Executeボタンをクリックします。ユーザーインターフェースは API と通信し、パラメータを送信し、結果を取得して画面に表示します
![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-05-swagger-04.png)
### 代替 API ドキュメントのアップグレード
### 代替 API ドキュメントのアップグレード { #alternative-api-docs-upgrade }
<a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>にアクセスしましょう
次に、<a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> にアクセスしま
- 代替の API ドキュメントにも新しいクエリパラメータやボディが反映されます。
* 代替のドキュメントにも新しいクエリパラメータやボディが反映されます。
![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png)
### まとめ
### まとめ { #recap }
要約すると、関数のパラメータとして、パラメータやボディ などの型を**一度だけ**宣言します。
要約すると、関数のパラメータとして、パラメータやボディなどの型を **一度だけ** 宣言します。
標準的な最新の Python の型を使っています。
標準的な最新の Python の型を使います。
新しい構文や特定のライブラリのメソッドやクラスなどを覚える必要はありません。
単なる標準的な**3.8 以降の Python**です。
単なる標準的な **Python** です。
例えば、`int`の場合:
例えば、`int` の場合:
```Python
item_id: int
```
または、より複雑な`Item`モデルの場合:
または、より複雑な `Item` モデルの場合:
```Python
item: Item
```
...そして、この一度の宣言で、以下のようになります:
...そして、この一度の宣言で、以下のようになります
- 以下を含むエディタサポート:
- 補完
- タイプチェック
- データの検証:
- データが無効な場合に自動でエラーをクリアします。
- 深い入れ子になった JSON オブジェクトでも検証が可能です。
- 入力データの<abbr title="also known as: serialization, parsing, marshalling">変換</abbr>: ネットワークから Python のデータや型に変換してから読み取ります:
- JSON.
- パスパラメータ
- クエリパラメータ
- クッキー
- ヘッダー
- フォーム
- ファイル
- 出力データの<abbr title="also known as: serialization, parsing, marshalling">変換</abbr>: Python のデータや型からネットワークデータへ変換します (JSON として):
- Convert Python types (`str`, `int`, `float`, `bool`, `list`, etc).
- `datetime` オブジェクト
- `UUID` オブジェクト
- データベースモデル
- ...などなど
- 2 つの代替ユーザーインターフェースを含む自動インタラクティブ API ドキュメント:
- Swagger UI.
- ReDoc.
* 以下を含むエディタサポート:
* 補完
* 型チェック
* データの検証:
* データが無効な場合に自動で明確なエラーをします。
* 深い入れ子になった JSON オブジェクトでも検証が可能です。
* 入力データの <abbr title="also known as: serialization, parsing, marshalling">変換</abbr>: ネットワークから Python のデータや型へ。以下から読み取ります:
* JSON
* パスパラメータ
* クエリパラメータ
* Cookie。
* ヘッダー
* フォーム
* ファイル
* 出力データの <abbr title="also known as: serialization, parsing, marshalling">変換</abbr>: Python のデータや型からネットワークデータへJSON として)変換します:
* Python の型(`str``int``float``bool``list` など)の変換。
* `datetime` オブジェクト
* `UUID` オブジェクト
* データベースモデル
* ...などなど
* 2 つの代替ユーザーインターフェースを含む自動対話型 API ドキュメント:
* Swagger UI
* ReDoc
---
コード例に戻りましょう、**FastAPI** は次のようになります:
前のコード例に戻ると、**FastAPI** は次のように動作します
- `GET`および`PUT`リクエストのパスに`item_id` があることを検証します。
- `item_id`が`GET`および`PUT`リクエストに対して`int` 型であることを検証します。
- そうでない場合、クライアントは有用で明確なエラーが表示されます。
- `GET` リクエストに対してオプションのクエリパラメータ `q` (`http://127.0.0.1:8000/items/foo?q=somequery` のように) が存在するかどうかを調べます。
- パラメータ `q` は `= None` で宣言されているので、オプションです。
- `None`がなければ必須になります(`PUT`の場合のボディと同様です)。
- `PUT` リクエストを `/items/{item_id}` に送信する場合、ボディを JSON として読み込みます:
- 必須の属性 `name` を確認してください。 それは `str` であるべきす。
- 必須の属性 `price` を確認してください。それは `float` でなければならないす。
- オプションの属性 `is_offer` を確認してください。値がある場合は`bool` であるべきす。
- これらはすべて、深くネストされた JSON オブジェクトに対しても動作します。
- JSON から JSON に自動的に変換します。
- OpenAPIですべてを文書化し、以下を使用することができます:
- 対話的なドキュメントシステム。
- 多くの言語に対応した自動クライアントコード生成システム。
- 2 つの対話的なドキュメントWebインターフェスを直接提供します。
* `GET` および `PUT` リクエストのパスに `item_id` があることを検証します。
* `GET` および `PUT` リクエストに対して `item_id` が `int` 型であることを検証します。
* そうでない場合、クライアントは有用で明確なエラーを受け取ります。
* `GET` リクエストに対して、`q` という名前のオプションのクエリパラメータ`http://127.0.0.1:8000/items/foo?q=somequery` のような)が存在するかどうかを調べます。
* `q` パラメータは `= None` で宣言されているため、オプションです。
* `None` がなければ必須になります(`PUT` の場合のボディと同様です)。
* `PUT` リクエストを `/items/{item_id}` に送信する場合、ボディを JSON として読み込みます:
* 必須の属性 `name` があり、`str` であるべきことを確認します。
* 必須の属性 `price` があり、`float` でなければならないことを確認します。
* オプションの属性 `is_offer` があり、存在する場合は `bool` であるべきことを確認します。
* これらはすべて、深くネストされた JSON オブジェクトに対しても動作します。
* JSON への/からの変換を自動的に行います。
* OpenAPI ですべてを文書化し、以下で利用できます:
* 対話ドキュメントシステム。
* 多くの言語に対応した自動クライアントコード生成システム。
* 2 つの対話ドキュメント Web インターフェスを直接提供します。
---
まだ表面的な部分に触れただけですが、もう全ての仕組みは分かっているはずです。
まだ表面的な部分に触れただけですが、仕組みはすでにイメージできているはずです。
以下の行を変更してみてください:
以下の行を変更してみてください
```Python
return {"item_name": item.name, "item_id": item_id}
```
...以下:
...以下:
```Python
... "item_name": item.name ...
```
...以下のように:
...:
```Python
... "item_price": item.price ...
```
...そして、エディタが属性を自動補完し、そのタイプを知る方法を確認してください。:
...に変更し、エディタが属性を自動補完し、そのを知ることを確認してください。
![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png)
より多くの機能を含む、より完全な例については、<a href="https://fastapi.tiangolo.com/tutorial/">チュートリアル - ユーザーガイド</a>をご覧ください。
より多くの機能を含む、より完全な例については、<a href="https://fastapi.tiangolo.com/ja/tutorial/">Tutorial - User Guide</a> を参照してください。
**ネタバレ注意**: チュートリアル - ユーザーガイドは以下の情報が含まれています:
**ネタバレ注意**: tutorial - user guide には以下が含まれます
- **ヘッダー**、**クッキー**、**フォームフィールド**、**ファイル**など他の場所からの **パラメータ** 宣言。
- `maximum_length``regex`のような**検証制約**を設定する方法。
- 非常に強力で使いやすい <abbr title="also known as components, resources, providers, services, injectables">**依存性注入**</abbr>システム。
- **JWT トークン**を用いた **OAuth2** や **HTTP Basic 認証** のサポートを含む、セキュリティと認証。
- **深くネストされた JSON モデル**を宣言するためのより高度な(しかし同様に簡単な)技術Pydantic のおかげです)。
- 以下のようなたくさんのおまけ機能(Starlette のおかげです):
- **WebSockets**
- **GraphQL**
- `httpx` や `pytest`をもとにした極限に簡単なテスト
- **CORS**
- **クッキーセッション**
- ...などなど。
* **ヘッダー**、**Cookie**、**フォームフィールド**、**ファイル**など他のさまざまな場所からの **パラメータ** 宣言。
* `maximum_length``regex` のような **検証制約** を設定する方法。
* 非常に強力で使いやすい **<abbr title="also known as components, resources, providers, services, injectables">依存性注入</abbr>** システム。
* **JWT トークン**を用いた **OAuth2** や **HTTP Basic** 認証のサポートを含む、セキュリティと認証。
* **深くネストされた JSON モデル**を宣言するためのより高度な(しかし同様に簡単な)手法Pydantic のおかげです)。
* <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> および他のライブラリによる **GraphQL** 統合。
* 以下のようなたくさんのおまけ機能Starlette のおかげです):
* **WebSockets**
* HTTPX と `pytest` に基づく極めて簡単なテスト
* **CORS**
* **Cookie Sessions**
* ...などなど。
## パフォーマンス
### アプリをデプロイ(任意) { #deploy-your-app-optional }
独立した TechEmpower のベンチマークでは、Uvicorn で動作する**FastAPI**アプリケーションが、<a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">Python フレームワークの中で最も高速なものの 1 つ</a>であり、Starlette と UvicornFastAPI で内部的に使用されています)にのみ下回っていると示されています。
必要に応じて FastAPI アプリ<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a> にデプロイできます。まだの場合はウェイティングリストに参加してください。 🚀
詳細は<a href="https://fastapi.tiangolo.com/benchmarks/" class="internal-link" target="_blank">ベンチマーク</a>セクションをご覧ください
すでに **FastAPI Cloud** アカウント(ウェイティングリストから招待されました 😉がある場合は、1 コマンドでアプリケーションをデプロイできます
## オプションの依存関係
デプロイ前に、ログインしていることを確認してください。
<div class="termy">
```console
$ fastapi login
You are logged in to FastAPI Cloud 🚀
```
</div>
次に、アプリをデプロイします。
<div class="termy">
```console
$ fastapi deploy
Deploying to FastAPI Cloud...
✅ Deployment successful!
🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
```
</div>
これで完了です!その URL でアプリにアクセスできます。 ✨
#### FastAPI Cloud について { #about-fastapi-cloud }
**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** は **FastAPI** の作者と同じチームによって作られています。
最小限の労力で API を **構築**、**デプロイ**、**アクセス** するためのプロセスを効率化します。
FastAPI でアプリを構築するのと同じ **開発者体験** を、クラウドへの **デプロイ** にももたらします。 🎉
FastAPI Cloud は *FastAPI and friends* オープンソースプロジェクトの主要スポンサーであり、資金提供元です。 ✨
#### 他のクラウドプロバイダにデプロイ { #deploy-to-other-cloud-providers }
FastAPI はオープンソースであり、標準に基づいています。選択した任意のクラウドプロバイダに FastAPI アプリをデプロイできます。
各クラウドプロバイダのガイドに従って、FastAPI アプリをデプロイしてください。 🤓
## パフォーマンス { #performance }
独立した TechEmpower のベンチマークでは、Uvicorn で動作する **FastAPI** アプリケーションが、<a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">利用可能な最も高速な Python フレームワークの一つ</a>であり、Starlette と UvicornFastAPI で内部的に使用されています)にのみ下回っていると示されています。(*
詳細は <a href="https://fastapi.tiangolo.com/ja/benchmarks/" class="internal-link" target="_blank">Benchmarks</a> セクションをご覧ください。
## 依存関係 { #dependencies }
FastAPI は Pydantic と Starlette に依存しています。
### `standard` 依存関係 { #standard-dependencies }
FastAPI を `pip install "fastapi[standard]"` でインストールすると、`standard` グループのオプション依存関係が含まれます。
Pydantic によって使用されるもの:
- <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email-validator</code></a> - E メール検証
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email-validator</code></a> - メール検証のため。
Starlette によって使用されるもの:
- <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - `TestClient`を使用するために必要です。
- <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - デフォルトのテンプレート設定を使用する場合必要です。
- <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>`request.form()`からの変換をサポートしたい場合必要です。
- <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - `SessionMiddleware` サポートのためには必要です。
- <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Starlette の `SchemaGenerator` サポートのために必要です。 (FastAPI では必要ないでしょう。)
- <a href="https://graphene-python.org/" target="_blank"><code>graphene</code></a> - `GraphQLApp` サポートのためには必要です。
* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - `TestClient` を使用したい場合に必要です。
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - デフォルトのテンプレート設定を使用したい場合必要です。
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - `request.form()` とともに、フォームの <abbr title="converting the string that comes from an HTTP request into Python data">parsing</abbr> をサポートしたい場合必要です。
FastAPI / Starlette に使用されるもの:
FastAPI によって使用されるもの:
- <a href="https://www.uvicorn.dev" target="_blank"><code>uvicorn</code></a> - アプリケーションをロードしてサーブするサーバーのため。
- <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - `ORJSONResponse`を使用したい場合は必要です。
- <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - `UJSONResponse`を使用する場合は必須です。
* <a href="https://www.uvicorn.dev" target="_blank"><code>uvicorn</code></a> - アプリケーションをロードして提供するサーバーのため。これには `uvicorn[standard]` も含まれ、高性能なサービングに必要な依存関係(例: `uvloop`)が含まれます。
* `fastapi-cli[standard]` - `fastapi` コマンドを提供します。
* これには `fastapi-cloud-cli` が含まれ、FastAPI アプリケーションを <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a> にデプロイできます。
これらは全て `pip install fastapi[all]`でインストールできます。
### `standard` 依存関係なし { #without-standard-dependencies }
## ライセンス
`standard` のオプション依存関係を含めたくない場合は、`pip install "fastapi[standard]"` の代わりに `pip install fastapi` でインストールできます。
このプロジェクトは MIT ライセンスです。
### `fastapi-cloud-cli` なし { #without-fastapi-cloud-cli }
標準の依存関係を含めつつ `fastapi-cloud-cli` を除外して FastAPI をインストールしたい場合は、`pip install "fastapi[standard-no-fastapi-cloud-cli]"` でインストールできます。
### 追加のオプション依存関係 { #additional-optional-dependencies }
追加でインストールしたい依存関係があります。
追加のオプション Pydantic 依存関係:
* <a href="https://docs.pydantic.dev/latest/usage/pydantic_settings/" target="_blank"><code>pydantic-settings</code></a> - 設定管理のため。
* <a href="https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/" target="_blank"><code>pydantic-extra-types</code></a> - Pydantic で使用する追加の型のため。
追加のオプション FastAPI 依存関係:
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - `ORJSONResponse` を使用したい場合に必要です。
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - `UJSONResponse` を使用したい場合に必要です。
## ライセンス { #license }
このプロジェクトは MIT ライセンスの条項の下でライセンスされています。

View File

@@ -1,5 +1,5 @@
# 学習
# 学習 { #learn }
ここでは、**FastAPI** を学習するための入門セクションとチュートリアルを紹介します。
これは、FastAPIを学習するにあたっての**書籍**や**コース**であり、**公式**かつ推奨される方法とみなすことができます 😎
これは、**書籍**や**コース**、FastAPIを学習するための**公式**かつ推奨される方法とみなすことができます😎

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