Browse Source

Merge branch 'master' into pass-none-when-null-received

pull/12135/head
Merlin 4 weeks ago
committed by GitHub
parent
commit
c90d831672
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 5
      .github/workflows/deploy-docs.yml
  2. 2
      .pre-commit-config.yaml
  3. 1
      README.md
  4. 2
      docs/az/docs/index.md
  5. 11
      docs/bn/docs/index.md
  6. 2
      docs/de/docs/index.md
  7. 16
      docs/de/docs/tutorial/query-params-str-validations.md
  8. 2
      docs/em/docs/index.md
  9. 28
      docs/em/docs/tutorial/query-params-str-validations.md
  10. 38
      docs/en/data/contributors.yml
  11. 177
      docs/en/data/github_sponsors.yml
  12. 3
      docs/en/data/members.yml
  13. 12
      docs/en/data/sponsors.yml
  14. 336
      docs/en/data/topic_repos.yml
  15. 199
      docs/en/data/translation_reviewers.yml
  16. 56
      docs/en/data/translators.yml
  17. 15
      docs/en/docs/advanced/index.md
  18. BIN
      docs/en/docs/img/sponsors/coderabbit-banner.png
  19. BIN
      docs/en/docs/img/sponsors/coderabbit.png
  20. BIN
      docs/en/docs/img/sponsors/lambdatest.png
  21. 88
      docs/en/docs/release-notes.md
  22. 2
      docs/en/docs/tutorial/body-multiple-params.md
  23. 181
      docs/en/docs/tutorial/query-params-str-validations.md
  24. 10
      docs/en/docs/tutorial/response-status-code.md
  25. 4
      docs/en/docs/virtual-environments.md
  26. 6
      docs/en/overrides/main.html
  27. 2
      docs/es/docs/index.md
  28. 16
      docs/es/docs/tutorial/query-params-str-validations.md
  29. 8
      docs/fa/docs/index.md
  30. 2
      docs/fr/docs/index.md
  31. 6
      docs/he/docs/index.md
  32. 2
      docs/hu/docs/index.md
  33. 2
      docs/id/docs/index.md
  34. 14
      docs/it/docs/index.md
  35. 13
      docs/ja/docs/index.md
  36. 77
      docs/ja/docs/tutorial/cookie-param-models.md
  37. 68
      docs/ja/docs/tutorial/query-param-models.md
  38. 313
      docs/ko/docs/advanced/custom-response.md
  39. 287
      docs/ko/docs/help-fastapi.md
  40. 11
      docs/ko/docs/index.md
  41. 273
      docs/ko/docs/tutorial/security/oauth2-jwt.md
  42. 18
      docs/ko/docs/tutorial/security/simple-oauth2.md
  43. 2
      docs/nl/docs/index.md
  44. 11
      docs/pl/docs/index.md
  45. 2
      docs/pt/docs/index.md
  46. 48
      docs/ru/docs/advanced/response-cookies.md
  47. 6
      docs/ru/docs/index.md
  48. 74
      docs/ru/docs/tutorial/middleware.md
  49. 28
      docs/ru/docs/tutorial/query-params-str-validations.md
  50. 2
      docs/tr/docs/index.md
  51. 2
      docs/uk/docs/index.md
  52. 170
      docs/uk/docs/tutorial/body-multiple-params.md
  53. 245
      docs/uk/docs/tutorial/body-nested-models.md
  54. 112
      docs/uk/docs/tutorial/debugging.md
  55. 91
      docs/uk/docs/tutorial/header-params.md
  56. 261
      docs/uk/docs/tutorial/path-params.md
  57. 192
      docs/uk/docs/tutorial/query-params.md
  58. 175
      docs/uk/docs/tutorial/request-files.md
  59. 78
      docs/uk/docs/tutorial/request-form-models.md
  60. 41
      docs/uk/docs/tutorial/request-forms-and-files.md
  61. 73
      docs/uk/docs/tutorial/request-forms.md
  62. 240
      docs/uk/docs/tutorial/testing.md
  63. 17
      docs/vi/docs/deployment/cloud.md
  64. 21
      docs/vi/docs/deployment/index.md
  65. 93
      docs/vi/docs/deployment/versions.md
  66. 2
      docs/vi/docs/index.md
  67. 40
      docs/vi/docs/tutorial/static-files.md
  68. 2
      docs/yo/docs/index.md
  69. 2
      docs/zh-hant/docs/index.md
  70. 8
      docs/zh/docs/index.md
  71. 27
      docs/zh/docs/tutorial/query-params-str-validations.md
  72. 2
      docs_src/configure_swagger_ui/tutorial002.py
  73. 11
      docs_src/query_params_str_validations/tutorial006b.py
  74. 12
      docs_src/query_params_str_validations/tutorial006b_an.py
  75. 13
      docs_src/query_params_str_validations/tutorial006b_an_py39.py
  76. 2
      docs_src/query_params_str_validations/tutorial006c.py
  77. 2
      docs_src/query_params_str_validations/tutorial006c_an.py
  78. 2
      docs_src/query_params_str_validations/tutorial006c_an_py310.py
  79. 2
      docs_src/query_params_str_validations/tutorial006c_an_py39.py
  80. 2
      docs_src/query_params_str_validations/tutorial006c_py310.py
  81. 11
      docs_src/query_params_str_validations/tutorial006d.py
  82. 12
      docs_src/query_params_str_validations/tutorial006d_an.py
  83. 13
      docs_src/query_params_str_validations/tutorial006d_an_py39.py
  84. 31
      docs_src/query_params_str_validations/tutorial015_an.py
  85. 30
      docs_src/query_params_str_validations/tutorial015_an_py310.py
  86. 30
      docs_src/query_params_str_validations/tutorial015_an_py39.py
  87. 2
      docs_src/security/tutorial004.py
  88. 2
      docs_src/security/tutorial004_an.py
  89. 2
      docs_src/security/tutorial004_an_py310.py
  90. 2
      docs_src/security/tutorial004_an_py39.py
  91. 2
      docs_src/security/tutorial004_py310.py
  92. 2
      docs_src/security/tutorial005_an.py
  93. 2
      docs_src/security/tutorial005_an_py310.py
  94. 6
      docs_src/security/tutorial005_an_py39.py
  95. 2
      fastapi/__init__.py
  96. 42
      fastapi/dependencies/utils.py
  97. 12
      fastapi/openapi/utils.py
  98. 24
      fastapi/routing.py
  99. 11
      fastapi/security/http.py
  100. 2
      pyproject.toml

5
.github/workflows/deploy-docs.yml

@ -62,10 +62,7 @@ jobs:
env:
PROJECT_NAME: fastapitiangolo
BRANCH: ${{ ( github.event.workflow_run.head_repository.full_name == github.repository && github.event.workflow_run.head_branch == 'master' && 'main' ) || ( github.event.workflow_run.head_sha ) }}
# TODO: Use v3 when it's fixed, probably in v3.11
# https://github.com/cloudflare/wrangler-action/issues/307
uses: cloudflare/[email protected]
# uses: cloudflare/wrangler-action@v3
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}

2
.pre-commit-config.yaml

@ -14,7 +14,7 @@ repos:
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.7.4
rev: v0.9.4
hooks:
- id: ruff
args:

1
README.md

@ -57,6 +57,7 @@ The key features are:
<a href="https://zuplo.link/fastapi-gh" target="_blank" title="Zuplo: Scale, Protect, Document, and Monetize your FastAPI"><img src="https://fastapi.tiangolo.com/img/sponsors/zuplo.png"></a>
<a href="https://liblab.com?utm_source=fastapi" target="_blank" title="liblab - Generate SDKs from FastAPI"><img src="https://fastapi.tiangolo.com/img/sponsors/liblab.png"></a>
<a href="https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi" target="_blank" title="Deploy & scale any full-stack web app on Render. Focus on building apps, not infra."><img src="https://fastapi.tiangolo.com/img/sponsors/render.svg"></a>
<a href="https://www.coderabbit.ai/?utm_source=fastapi&utm_medium=badge&utm_campaign=fastapi" target="_blank" title="Cut Code Review Time & Bugs in Half with CodeRabbit"><img src="https://fastapi.tiangolo.com/img/sponsors/coderabbit.png"></a>
<a href="https://github.com/deepset-ai/haystack/" target="_blank" title="Build powerful search from composable, open source building blocks"><img src="https://fastapi.tiangolo.com/img/sponsors/haystack-fastapi.svg"></a>
<a href="https://databento.com/" target="_blank" title="Pay as you go for market data"><img src="https://fastapi.tiangolo.com/img/sponsors/databento.svg"></a>
<a href="https://speakeasy.com?utm_source=fastapi+repo&utm_medium=github+sponsorship" target="_blank" title="SDKs for your API | Speakeasy"><img src="https://fastapi.tiangolo.com/img/sponsors/speakeasy.png"></a>

2
docs/az/docs/index.md

@ -6,7 +6,7 @@
</p>
<p align="center">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Əhatə">

11
docs/bn/docs/index.md

@ -5,15 +5,18 @@
<em>FastAPI উচ্চক্ষমতা সম্পন্ন, সহজে শেখার এবং দ্রুত কোড করে প্রোডাকশনের জন্য ফ্রামওয়ার্ক।</em>
</p>
<p align="center">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest" target="_blank">
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg" alt="Test">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://codecov.io/gh/fastapi/fastapi" target="_blank">
<img src="https://img.shields.io/codecov/c/github/fastapi/fastapi?color=%2334D058" alt="Coverage">
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">
</a>
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Package version">
</a>
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://img.shields.io/pypi/pyversions/fastapi.svg?color=%2334D058" alt="Supported Python versions">
</a>
</p>
---

2
docs/de/docs/index.md

@ -12,7 +12,7 @@
</p>
<p align="center">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">

16
docs/de/docs/tutorial/query-params-str-validations.md

@ -315,22 +315,6 @@ Wenn Sie einen Parameter erforderlich machen wollen, während Sie `Query` verwen
{* ../../docs_src/query_params_str_validations/tutorial006_an_py39.py hl[9] *}
### Erforderlich mit Ellipse (`...`)
Es gibt eine Alternative, die explizit deklariert, dass ein Wert erforderlich ist. Sie können als Default das <abbr title='Zeichenfolge, die einen Wert direkt darstellt, etwa 1, "hallowelt", True, None'>Literal</abbr> `...` setzen:
{* ../../docs_src/query_params_str_validations/tutorial006b_an_py39.py hl[9] *}
/// info
Falls Sie das `...` bisher noch nicht gesehen haben: Es ist ein spezieller einzelner Wert, <a href="https://docs.python.org/3/library/constants.html#Ellipsis" class="external-link" target="_blank">Teil von Python und wird „Ellipsis“ genannt</a> (Deutsch: Ellipse).
Es wird von Pydantic und FastAPI verwendet, um explizit zu deklarieren, dass ein Wert erforderlich ist.
///
Dies wird **FastAPI** wissen lassen, dass dieser Parameter erforderlich ist.
### Erforderlich, kann `None` sein
Sie können deklarieren, dass ein Parameter `None` akzeptiert, aber dennoch erforderlich ist. Das zwingt Clients, den Wert zu senden, selbst wenn er `None` ist.

2
docs/em/docs/index.md

@ -12,7 +12,7 @@
</p>
<p align="center">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">

28
docs/em/docs/tutorial/query-params-str-validations.md

@ -148,22 +148,6 @@ q: Union[str, None] = Query(default=None, min_length=3)
{* ../../docs_src/query_params_str_validations/tutorial006.py hl[7] *}
### ✔ ⏮️ ❕ (`...`)
📤 🎛 🌌 🎯 📣 👈 💲 ✔. 👆 💪 ⚒ `default` 🔢 🔑 💲 `...`:
{* ../../docs_src/query_params_str_validations/tutorial006b.py hl[7] *}
/// info
🚥 👆 🚫 👀 👈 `...` ⏭: ⚫️ 🎁 👁 💲, ⚫️ <a href="https://docs.python.org/3/library/constants.html#Ellipsis" class="external-link" target="_blank">🍕 🐍 &amp; 🤙 "❕"</a>.
⚫️ ⚙️ Pydantic &amp; FastAPI 🎯 📣 👈 💲 ✔.
///
👉 🔜 ➡️ **FastAPI** 💭 👈 👉 🔢 ✔.
### ✔ ⏮️ `None`
👆 💪 📣 👈 🔢 💪 🚫 `None`, ✋️ 👈 ⚫️ ✔. 👉 🔜 ⚡ 👩‍💻 📨 💲, 🚥 💲 `None`.
@ -178,18 +162,6 @@ Pydantic, ❔ ⚫️❔ 🏋️ 🌐 💽 🔬 &amp; 🛠️ FastAPI, ✔️
///
### ⚙️ Pydantic `Required` ↩️ ❕ (`...`)
🚥 👆 💭 😬 ⚙️ `...`, 👆 💪 🗄 &amp; ⚙️ `Required` ⚪️➡️ Pydantic:
{* ../../docs_src/query_params_str_validations/tutorial006d.py hl[2,8] *}
/// tip
💭 👈 🌅 💼, 🕐❔ 🕳 🚚, 👆 💪 🎯 🚫 `default` 🔢, 👆 🛎 🚫 ✔️ ⚙️ `...` 🚫 `Required`.
///
## 🔢 🔢 📇 / 💗 💲
🕐❔ 👆 🔬 🔢 🔢 🎯 ⏮️ `Query` 👆 💪 📣 ⚫️ 📨 📇 💲, ⚖️ 🙆‍♀ 🎏 🌌, 📨 💗 💲.

38
docs/en/data/contributors.yml

@ -1,11 +1,11 @@
tiangolo:
login: tiangolo
count: 713
count: 723
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
url: https://github.com/tiangolo
dependabot:
login: dependabot
count: 90
count: 94
avatarUrl: https://avatars.githubusercontent.com/in/29110?v=4
url: https://github.com/apps/dependabot
alejsdev:
@ -68,6 +68,11 @@ vishnuvskvkl:
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/84698110?u=8af5de0520dd4fa195f53c2850a26f57c0f6bc64&v=4
url: https://github.com/vishnuvskvkl
svlandeg:
login: svlandeg
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4
url: https://github.com/svlandeg
alissadb:
login: alissadb
count: 6
@ -88,16 +93,16 @@ waynerv:
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
url: https://github.com/waynerv
svlandeg:
login: svlandeg
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4
url: https://github.com/svlandeg
krishnamadhavan:
login: krishnamadhavan
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/31798870?u=950693b28f3ae01105fd545c046e46ca3d31ab06&v=4
url: https://github.com/krishnamadhavan
alv2017:
login: alv2017
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
url: https://github.com/alv2017
jekirl:
login: jekirl
count: 4
@ -121,7 +126,7 @@ adriangb:
iudeen:
login: iudeen
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4
avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=f09cdd745e5bf16138f29b42732dd57c7f02bee1&v=4
url: https://github.com/iudeen
philipokiokio:
login: philipokiokio
@ -211,7 +216,7 @@ TeoZosa:
graingert:
login: graingert
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/413772?u=64b77b6aa405c68a9c6bcf45f84257c66eea5f32&v=4
avatarUrl: https://avatars.githubusercontent.com/u/413772?v=4
url: https://github.com/graingert
jaystone776:
login: jaystone776
@ -233,6 +238,11 @@ papb:
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/20914054?u=890511fae7ea90d887e2a65ce44a1775abba38d5&v=4
url: https://github.com/papb
musicinmybrain:
login: musicinmybrain
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/6898909?u=9010312053e7141383b9bdf538036c7f37fbaba0&v=4
url: https://github.com/musicinmybrain
gitworkflows:
login: gitworkflows
count: 3
@ -468,11 +478,6 @@ yezz123:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/52716203?u=d7062cbc6eb7671d5dc9cc0e32a24ae335e0f225&v=4
url: https://github.com/yezz123
musicinmybrain:
login: musicinmybrain
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/6898909?u=9010312053e7141383b9bdf538036c7f37fbaba0&v=4
url: https://github.com/musicinmybrain
softwarebloat:
login: softwarebloat
count: 2
@ -518,3 +523,8 @@ DanielKusyDev:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/36250676?u=2ea6114ff751fc48b55f231987a0e2582c6b1bd2&v=4
url: https://github.com/DanielKusyDev
DanielYang59:
login: DanielYang59
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/80093591?u=63873f701c7c74aac83c906800a1dddc0bc8c92f&v=4
url: https://github.com/DanielYang59

177
docs/en/data/github_sponsors.yml

@ -1,10 +1,10 @@
sponsors:
- - login: bump-sh
avatarUrl: https://avatars.githubusercontent.com/u/33217836?v=4
url: https://github.com/bump-sh
- login: renderinc
- - login: renderinc
avatarUrl: https://avatars.githubusercontent.com/u/36424661?v=4
url: https://github.com/renderinc
- login: bump-sh
avatarUrl: https://avatars.githubusercontent.com/u/33217836?v=4
url: https://github.com/bump-sh
- login: Nixtla
avatarUrl: https://avatars.githubusercontent.com/u/79945230?v=4
url: https://github.com/Nixtla
@ -23,6 +23,9 @@ sponsors:
- 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: porter-dev
avatarUrl: https://avatars.githubusercontent.com/u/62078005?v=4
url: https://github.com/porter-dev
@ -59,6 +62,9 @@ sponsors:
- login: Ponte-Energy-Partners
avatarUrl: https://avatars.githubusercontent.com/u/114745848?v=4
url: https://github.com/Ponte-Energy-Partners
- login: LambdaTest-Inc
avatarUrl: https://avatars.githubusercontent.com/u/171592363?u=96606606a45fa170427206199014f2a5a2a4920b&v=4
url: https://github.com/LambdaTest-Inc
- login: BoostryJP
avatarUrl: https://avatars.githubusercontent.com/u/57932412?v=4
url: https://github.com/BoostryJP
@ -80,9 +86,6 @@ sponsors:
- login: yasyf
avatarUrl: https://avatars.githubusercontent.com/u/709645?u=f36736b3c6a85f578886ecc42a740e7b436e7a01&v=4
url: https://github.com/yasyf
- - login: genzou9201
avatarUrl: https://avatars.githubusercontent.com/u/42960762?u=1ca6c18c59e8b327ae584c545b72de31ebc05275&v=4
url: https://github.com/genzou9201
- - login: primer-io
avatarUrl: https://avatars.githubusercontent.com/u/62146168?v=4
url: https://github.com/primer-io
@ -98,24 +101,18 @@ sponsors:
- - login: samuelcolvin
avatarUrl: https://avatars.githubusercontent.com/u/4039449?u=42eb3b833047c8c4b4f647a031eaef148c16d93f&v=4
url: https://github.com/samuelcolvin
- login: ProteinQure
avatarUrl: https://avatars.githubusercontent.com/u/33707203?v=4
url: https://github.com/ProteinQure
- login: vincentkoc
avatarUrl: https://avatars.githubusercontent.com/u/25068?u=fbd5b2d51142daa4bdbc21e21953a3b8b8188a4a&v=4
url: https://github.com/vincentkoc
- login: ddilidili
avatarUrl: https://avatars.githubusercontent.com/u/42176885?u=c0a849dde06987434653197b5f638d3deb55fc6c&v=4
url: https://github.com/ddilidili
- login: otosky
avatarUrl: https://avatars.githubusercontent.com/u/42260747?u=69d089387c743d89427aa4ad8740cfb34045a9e0&v=4
url: https://github.com/otosky
- 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: ramonalmeidam
avatarUrl: https://avatars.githubusercontent.com/u/45269580?u=3358750b3a5854d7c3ed77aaca7dd20a0f529d32&v=4
url: https://github.com/ramonalmeidam
- login: sepsi77
avatarUrl: https://avatars.githubusercontent.com/u/18682303?v=4
url: https://github.com/sepsi77
@ -140,11 +137,17 @@ sponsors:
- login: Leay15
avatarUrl: https://avatars.githubusercontent.com/u/32212558?u=c4aa9c1737e515959382a5515381757b1fd86c53&v=4
url: https://github.com/Leay15
- login: BoYanZh
avatarUrl: https://avatars.githubusercontent.com/u/32470225?u=55b174d080382822759d74307f8a0355fa86e808&v=4
url: https://github.com/BoYanZh
- login: ygorpontelo
avatarUrl: https://avatars.githubusercontent.com/u/32963605?u=35f7103f9c4c4c2589ae5737ee882e9375ef072e&v=4
url: https://github.com/ygorpontelo
- login: ProteinQure
avatarUrl: https://avatars.githubusercontent.com/u/33707203?v=4
url: https://github.com/ProteinQure
- login: chickenandstats
avatarUrl: https://avatars.githubusercontent.com/u/79477966?v=4
avatarUrl: https://avatars.githubusercontent.com/u/79477966?u=ae2b894aa954070db1d7830dab99b49eba4e4567&v=4
url: https://github.com/chickenandstats
- login: kaoru0310
avatarUrl: https://avatars.githubusercontent.com/u/80977929?u=1b61d10142b490e56af932ddf08a390fae8ee94f&v=4
@ -164,12 +167,6 @@ sponsors:
- login: logic-automation
avatarUrl: https://avatars.githubusercontent.com/u/144732884?v=4
url: https://github.com/logic-automation
- login: Torqsight-Labs
avatarUrl: https://avatars.githubusercontent.com/u/169598176?v=4
url: https://github.com/Torqsight-Labs
- login: ramonalmeidam
avatarUrl: https://avatars.githubusercontent.com/u/45269580?u=3358750b3a5854d7c3ed77aaca7dd20a0f529d32&v=4
url: https://github.com/ramonalmeidam
- login: roboflow
avatarUrl: https://avatars.githubusercontent.com/u/53104118?v=4
url: https://github.com/roboflow
@ -185,12 +182,6 @@ sponsors:
- login: patricioperezv
avatarUrl: https://avatars.githubusercontent.com/u/73832292?u=5f471f156e19ee7920e62ae0f4a47b95580e61cf&v=4
url: https://github.com/patricioperezv
- login: mintuhouse
avatarUrl: https://avatars.githubusercontent.com/u/769950?u=ecfbd79a97d33177e0d093ddb088283cf7fe8444&v=4
url: https://github.com/mintuhouse
- login: tcsmith
avatarUrl: https://avatars.githubusercontent.com/u/989034?u=7d8d741552b3279e8f4d3878679823a705a46f8f&v=4
url: https://github.com/tcsmith
- login: dodo5522
avatarUrl: https://avatars.githubusercontent.com/u/1362607?u=9bf1e0e520cccc547c046610c468ce6115bbcf9f&v=4
url: https://github.com/dodo5522
@ -218,9 +209,15 @@ sponsors:
- login: anomaly
avatarUrl: https://avatars.githubusercontent.com/u/3654837?v=4
url: https://github.com/anomaly
- login: vincentkoc
avatarUrl: https://avatars.githubusercontent.com/u/25068?u=fbd5b2d51142daa4bdbc21e21953a3b8b8188a4a&v=4
url: https://github.com/vincentkoc
- 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=48f68868db8886fce31a1d802c1003914c6cd7c6&v=4
url: https://github.com/Ryandaydev
- login: jaredtrog
avatarUrl: https://avatars.githubusercontent.com/u/4381365?v=4
url: https://github.com/jaredtrog
- login: jstanden
avatarUrl: https://avatars.githubusercontent.com/u/63288?u=c3658d57d2862c607a0e19c2101c3c51876e36ad&v=4
url: https://github.com/jstanden
@ -251,12 +248,12 @@ sponsors:
- 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: TrevorBenson
avatarUrl: https://avatars.githubusercontent.com/u/9167887?u=dccbea3327a57750923333d8ebf1a0b3f1948949&v=4
url: https://github.com/TrevorBenson
- login: kaangiray26
avatarUrl: https://avatars.githubusercontent.com/u/11297495?u=e85327a77db45906d44f3ff06dd7f3303c644096&v=4
url: https://github.com/kaangiray26
- login: wdwinslow
avatarUrl: https://avatars.githubusercontent.com/u/11562137?u=dc01daafb354135603a263729e3d26d939c0c452&v=4
url: https://github.com/wdwinslow
@ -272,21 +269,18 @@ sponsors:
- login: dannywade
avatarUrl: https://avatars.githubusercontent.com/u/13680237?u=418ee985bd41577b20fde81417fb2d901e875e8a&v=4
url: https://github.com/dannywade
- 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=48f68868db8886fce31a1d802c1003914c6cd7c6&v=4
url: https://github.com/Ryandaydev
- login: jaredtrog
avatarUrl: https://avatars.githubusercontent.com/u/4381365?v=4
url: https://github.com/jaredtrog
- 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: oliverxchen
avatarUrl: https://avatars.githubusercontent.com/u/4471774?u=534191f25e32eeaadda22dfab4b0a428733d5489&v=4
url: https://github.com/oliverxchen
- login: ennui93
avatarUrl: https://avatars.githubusercontent.com/u/5300907?u=5b5452725ddb391b2caaebf34e05aba873591c3a&v=4
url: https://github.com/ennui93
- login: ternaus
avatarUrl: https://avatars.githubusercontent.com/u/5481618?u=513a26b02a39e7a28d587cd37c6cc877ea368e6e&v=4
url: https://github.com/ternaus
@ -308,9 +302,6 @@ sponsors:
- - login: pawamoy
avatarUrl: https://avatars.githubusercontent.com/u/3999221?u=b030e4c89df2f3a36bc4710b925bdeb6745c9856&v=4
url: https://github.com/pawamoy
- login: engineerjoe440
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
url: https://github.com/bnkc
@ -323,15 +314,12 @@ sponsors:
- login: mobyw
avatarUrl: https://avatars.githubusercontent.com/u/44370805?v=4
url: https://github.com/mobyw
- login: PelicanQ
avatarUrl: https://avatars.githubusercontent.com/u/77930606?v=4
url: https://github.com/PelicanQ
- login: TheR1D
avatarUrl: https://avatars.githubusercontent.com/u/16740832?u=b0dfdbdb27b79729430c71c6128962f77b7b53f7&v=4
url: https://github.com/TheR1D
- login: joshuatz
avatarUrl: https://avatars.githubusercontent.com/u/17817563?u=f1bf05b690d1fc164218f0b420cdd3acb7913e21&v=4
url: https://github.com/joshuatz
- login: ArtyomVancyan
avatarUrl: https://avatars.githubusercontent.com/u/44609997?v=4
url: https://github.com/ArtyomVancyan
- login: caviri
avatarUrl: https://avatars.githubusercontent.com/u/45425937?u=4e14bd64282bad8f385eafbdb004b5a279366d6e&v=4
url: https://github.com/caviri
- login: SebTota
avatarUrl: https://avatars.githubusercontent.com/u/25122511?v=4
url: https://github.com/SebTota
@ -350,12 +338,9 @@ sponsors:
- login: dvlpjrs
avatarUrl: https://avatars.githubusercontent.com/u/32254642?u=fbd6ad0324d4f1eb6231cf775be1c7bd4404e961&v=4
url: https://github.com/dvlpjrs
- login: ArtyomVancyan
avatarUrl: https://avatars.githubusercontent.com/u/44609997?v=4
url: https://github.com/ArtyomVancyan
- login: caviri
avatarUrl: https://avatars.githubusercontent.com/u/45425937?u=4e14bd64282bad8f385eafbdb004b5a279366d6e&v=4
url: https://github.com/caviri
- login: engineerjoe440
avatarUrl: https://avatars.githubusercontent.com/u/33275230?u=eb223cad27017bb1e936ee9b429b450d092d0236&v=4
url: https://github.com/engineerjoe440
- login: hgalytoby
avatarUrl: https://avatars.githubusercontent.com/u/50397689?u=62c7ff3519858423579676cd0efbd7e3f1ffe63a&v=4
url: https://github.com/hgalytoby
@ -368,9 +353,9 @@ sponsors:
- login: PunRabbit
avatarUrl: https://avatars.githubusercontent.com/u/70463212?u=1a835cfbc99295a60c8282f6aa6199d1b42241a5&v=4
url: https://github.com/PunRabbit
- login: tochikuji
avatarUrl: https://avatars.githubusercontent.com/u/851759?v=4
url: https://github.com/tochikuji
- login: PelicanQ
avatarUrl: https://avatars.githubusercontent.com/u/77930606?v=4
url: https://github.com/PelicanQ
- login: browniebroke
avatarUrl: https://avatars.githubusercontent.com/u/861044?u=5abfca5588f3e906b31583d7ee62f6de4b68aa24&v=4
url: https://github.com/browniebroke
@ -389,9 +374,6 @@ sponsors:
- login: Alisa-lisa
avatarUrl: https://avatars.githubusercontent.com/u/4137964?u=e7e393504f554f4ff15863a1e01a5746863ef9ce&v=4
url: https://github.com/Alisa-lisa
- login: hcristea
avatarUrl: https://avatars.githubusercontent.com/u/7814406?u=61d7a4fcf846983a4606788eac25e1c6c1209ba8&v=4
url: https://github.com/hcristea
- login: ddanier
avatarUrl: https://avatars.githubusercontent.com/u/113563?u=ed1dc79de72f93bd78581f88ebc6952b62f472da&v=4
url: https://github.com/ddanier
@ -404,15 +386,9 @@ sponsors:
- login: ceb10n
avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
url: https://github.com/ceb10n
- login: eteq
avatarUrl: https://avatars.githubusercontent.com/u/346587?v=4
url: https://github.com/eteq
- login: securancy
avatarUrl: https://avatars.githubusercontent.com/u/606673?v=4
url: https://github.com/securancy
- login: moonape1226
avatarUrl: https://avatars.githubusercontent.com/u/8532038?u=d9f8b855a429fff9397c3833c2ff83849ebf989d&v=4
url: https://github.com/moonape1226
- login: tochikuji
avatarUrl: https://avatars.githubusercontent.com/u/851759?v=4
url: https://github.com/tochikuji
- login: msehnout
avatarUrl: https://avatars.githubusercontent.com/u/9369632?u=8c988f1b008a3f601385a3616f9327820f66e3a5&v=4
url: https://github.com/msehnout
@ -420,7 +396,7 @@ sponsors:
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?v=4
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
@ -434,18 +410,18 @@ sponsors:
- login: pheanex
avatarUrl: https://avatars.githubusercontent.com/u/10408624?u=5b6bab6ee174aa6e991333e06eb29f628741013d&v=4
url: https://github.com/pheanex
- login: dzoladz
avatarUrl: https://avatars.githubusercontent.com/u/10561752?u=5ee314d54aa79592c18566827ad8914debd5630d&v=4
url: https://github.com/dzoladz
- login: Zuzah
avatarUrl: https://avatars.githubusercontent.com/u/10934846?u=1ef43e075ddc87bd1178372bf4d95ee6175cae27&v=4
url: https://github.com/Zuzah
- login: artempronevskiy
avatarUrl: https://avatars.githubusercontent.com/u/12235104?u=03df6e1e55c9c6fe5d230adabb8dd7d43d8bbe8f&v=4
url: https://github.com/artempronevskiy
- login: Graeme22
avatarUrl: https://avatars.githubusercontent.com/u/4185684?u=498182a42300d7bcd4de1215190cb17eb501136c&v=4
url: https://github.com/Graeme22
- login: TheR1D
avatarUrl: https://avatars.githubusercontent.com/u/16740832?u=b0dfdbdb27b79729430c71c6128962f77b7b53f7&v=4
url: https://github.com/TheR1D
- login: joshuatz
avatarUrl: https://avatars.githubusercontent.com/u/17817563?u=f1bf05b690d1fc164218f0b420cdd3acb7913e21&v=4
url: https://github.com/joshuatz
- login: danielunderwood
avatarUrl: https://avatars.githubusercontent.com/u/4472301?v=4
url: https://github.com/danielunderwood
@ -470,6 +446,12 @@ sponsors:
- login: harsh183
avatarUrl: https://avatars.githubusercontent.com/u/7780198?v=4
url: https://github.com/harsh183
- login: hcristea
avatarUrl: https://avatars.githubusercontent.com/u/7814406?u=19092923a4ea5b338567961c8270b9206a6d81bb&v=4
url: https://github.com/hcristea
- login: moonape1226
avatarUrl: https://avatars.githubusercontent.com/u/8532038?u=d9f8b855a429fff9397c3833c2ff83849ebf989d&v=4
url: https://github.com/moonape1226
- - login: larsyngvelundin
avatarUrl: https://avatars.githubusercontent.com/u/34173819?u=74958599695bf83ac9f1addd935a51548a10c6b0&v=4
url: https://github.com/larsyngvelundin
@ -479,6 +461,9 @@ sponsors:
- login: rwxd
avatarUrl: https://avatars.githubusercontent.com/u/40308458?u=cd04a39e3655923be4f25c2ba8a5a07b3da3230a&v=4
url: https://github.com/rwxd
- login: morzan1001
avatarUrl: https://avatars.githubusercontent.com/u/47593005?u=c30ab7230f82a12a9b938dcb54f84a996931409a&v=4
url: https://github.com/morzan1001
- login: sadikkuzu
avatarUrl: https://avatars.githubusercontent.com/u/23168063?u=d179c06bb9f65c4167fcab118526819f8e0dac17&v=4
url: https://github.com/sadikkuzu
@ -488,12 +473,12 @@ sponsors:
- login: FabulousCodingFox
avatarUrl: https://avatars.githubusercontent.com/u/78906517?u=924a27cbee3db7e0ece5cc1509921402e1445e74&v=4
url: https://github.com/FabulousCodingFox
- login: gateremark
avatarUrl: https://avatars.githubusercontent.com/u/91592218?u=969314eb2cfb035196f4d19499ec6f5050d7583a&v=4
url: https://github.com/gateremark
- login: morzan1001
avatarUrl: https://avatars.githubusercontent.com/u/47593005?u=c30ab7230f82a12a9b938dcb54f84a996931409a&v=4
url: https://github.com/morzan1001
- login: anqorithm
avatarUrl: https://avatars.githubusercontent.com/u/61029571?u=468256fa4e2d9ce2870b608299724bebb7a33f18&v=4
url: https://github.com/anqorithm
- login: Materacl
avatarUrl: https://avatars.githubusercontent.com/u/70155818?u=ae11d084518856127cca483816a91a187e3124ee&v=4
url: https://github.com/Materacl
- login: Toothwitch
avatarUrl: https://avatars.githubusercontent.com/u/1710406?u=5eebb23b46cd26e48643b9e5179536cad491c17a&v=4
url: https://github.com/Toothwitch

3
docs/en/data/members.yml

@ -17,3 +17,6 @@ members:
- login: patrick91
avatar_url: https://avatars.githubusercontent.com/u/667029
url: https://github.com/patrick91
- login: luzzodev
avatar_url: https://avatars.githubusercontent.com/u/27291415
url: https://github.com/luzzodev

12
docs/en/data/sponsors.yml

@ -32,6 +32,9 @@ gold:
- url: https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi
title: Deploy & scale any full-stack web app on Render. Focus on building apps, not infra.
img: https://fastapi.tiangolo.com/img/sponsors/render.svg
- url: https://www.coderabbit.ai/?utm_source=fastapi&utm_medium=badge&utm_campaign=fastapi
title: Cut Code Review Time & Bugs in Half with CodeRabbit
img: https://fastapi.tiangolo.com/img/sponsors/coderabbit.png
silver:
- url: https://github.com/deepset-ai/haystack/
title: Build powerful search from composable, open source building blocks
@ -55,6 +58,9 @@ bronze:
- url: https://www.exoflare.com/open-source/?utm_source=FastAPI&utm_campaign=open_source
title: Biosecurity risk assessments made easy.
img: https://fastapi.tiangolo.com/img/sponsors/exoflare.png
- 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://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

336
docs/en/data/topic_repos.yml

@ -1,86 +1,86 @@
- name: full-stack-fastapi-template
html_url: https://github.com/fastapi/full-stack-fastapi-template
stars: 29409
stars: 30645
owner_login: fastapi
owner_html_url: https://github.com/fastapi
- name: Hello-Python
html_url: https://github.com/mouredev/Hello-Python
stars: 28113
stars: 28690
owner_login: mouredev
owner_html_url: https://github.com/mouredev
- name: serve
html_url: https://github.com/jina-ai/serve
stars: 21264
stars: 21356
owner_login: jina-ai
owner_html_url: https://github.com/jina-ai
- name: sqlmodel
html_url: https://github.com/fastapi/sqlmodel
stars: 15109
stars: 15312
owner_login: fastapi
owner_html_url: https://github.com/fastapi
- name: HivisionIDPhotos
html_url: https://github.com/Zeyi-Lin/HivisionIDPhotos
stars: 14564
stars: 14957
owner_login: Zeyi-Lin
owner_html_url: https://github.com/Zeyi-Lin
- name: Douyin_TikTok_Download_API
html_url: https://github.com/Evil0ctal/Douyin_TikTok_Download_API
stars: 10701
stars: 11192
owner_login: Evil0ctal
owner_html_url: https://github.com/Evil0ctal
- name: fastapi-best-practices
html_url: https://github.com/zhanymkanov/fastapi-best-practices
stars: 10180
stars: 10501
owner_login: zhanymkanov
owner_html_url: https://github.com/zhanymkanov
- name: awesome-fastapi
html_url: https://github.com/mjhea0/awesome-fastapi
stars: 9061
stars: 9193
owner_login: mjhea0
owner_html_url: https://github.com/mjhea0
- name: FastUI
html_url: https://github.com/pydantic/FastUI
stars: 8644
stars: 8721
owner_login: pydantic
owner_html_url: https://github.com/pydantic
- name: nonebot2
html_url: https://github.com/nonebot/nonebot2
stars: 6312
stars: 6433
owner_login: nonebot
owner_html_url: https://github.com/nonebot
- name: serge
html_url: https://github.com/serge-chat/serge
stars: 5686
stars: 5699
owner_login: serge-chat
owner_html_url: https://github.com/serge-chat
- name: FileCodeBox
html_url: https://github.com/vastsa/FileCodeBox
stars: 4933
stars: 5534
owner_login: vastsa
owner_html_url: https://github.com/vastsa
- name: fastapi-users
html_url: https://github.com/fastapi-users/fastapi-users
stars: 4849
stars: 4921
owner_login: fastapi-users
owner_html_url: https://github.com/fastapi-users
- name: polar
html_url: https://github.com/polarsource/polar
stars: 4598
owner_login: polarsource
owner_html_url: https://github.com/polarsource
- name: hatchet
html_url: https://github.com/hatchet-dev/hatchet
stars: 4514
stars: 4585
owner_login: hatchet-dev
owner_html_url: https://github.com/hatchet-dev
- name: chatgpt-web-share
html_url: https://github.com/chatpire/chatgpt-web-share
stars: 4319
stars: 4318
owner_login: chatpire
owner_html_url: https://github.com/chatpire
- name: polar
html_url: https://github.com/polarsource/polar
stars: 4216
owner_login: polarsource
owner_html_url: https://github.com/polarsource
- name: strawberry
html_url: https://github.com/strawberry-graphql/strawberry
stars: 4126
stars: 4180
owner_login: strawberry-graphql
owner_html_url: https://github.com/strawberry-graphql
- name: atrilabs-engine
@ -90,279 +90,284 @@
owner_html_url: https://github.com/Atri-Labs
- name: dynaconf
html_url: https://github.com/dynaconf/dynaconf
stars: 3874
stars: 3904
owner_login: dynaconf
owner_html_url: https://github.com/dynaconf
- name: poem
html_url: https://github.com/poem-web/poem
stars: 3746
stars: 3781
owner_login: poem-web
owner_html_url: https://github.com/poem-web
- name: opyrator
html_url: https://github.com/ml-tooling/opyrator
stars: 3117
owner_login: ml-tooling
owner_html_url: https://github.com/ml-tooling
- name: farfalle
html_url: https://github.com/rashadphz/farfalle
stars: 3094
stars: 3190
owner_login: rashadphz
owner_html_url: https://github.com/rashadphz
- name: opyrator
html_url: https://github.com/ml-tooling/opyrator
stars: 3119
owner_login: ml-tooling
owner_html_url: https://github.com/ml-tooling
- name: fastapi-admin
html_url: https://github.com/fastapi-admin/fastapi-admin
stars: 3040
stars: 3086
owner_login: fastapi-admin
owner_html_url: https://github.com/fastapi-admin
- name: docarray
html_url: https://github.com/docarray/docarray
stars: 3007
stars: 3021
owner_login: docarray
owner_html_url: https://github.com/docarray
- name: datamodel-code-generator
html_url: https://github.com/koxudaxi/datamodel-code-generator
stars: 2914
stars: 2988
owner_login: koxudaxi
owner_html_url: https://github.com/koxudaxi
- name: fastapi-realworld-example-app
html_url: https://github.com/nsidnev/fastapi-realworld-example-app
stars: 2840
owner_login: nsidnev
owner_html_url: https://github.com/nsidnev
- name: LitServe
html_url: https://github.com/Lightning-AI/LitServe
stars: 2804
stars: 2863
owner_login: Lightning-AI
owner_html_url: https://github.com/Lightning-AI
- name: uvicorn-gunicorn-fastapi-docker
html_url: https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker
stars: 2730
owner_login: tiangolo
owner_html_url: https://github.com/tiangolo
- name: fastapi-realworld-example-app
html_url: https://github.com/nsidnev/fastapi-realworld-example-app
stars: 2850
owner_login: nsidnev
owner_html_url: https://github.com/nsidnev
- name: logfire
html_url: https://github.com/pydantic/logfire
stars: 2620
stars: 2757
owner_login: pydantic
owner_html_url: https://github.com/pydantic
- name: uvicorn-gunicorn-fastapi-docker
html_url: https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker
stars: 2731
owner_login: tiangolo
owner_html_url: https://github.com/tiangolo
- name: huma
html_url: https://github.com/danielgtaylor/huma
stars: 2567
stars: 2700
owner_login: danielgtaylor
owner_html_url: https://github.com/danielgtaylor
- name: tracecat
html_url: https://github.com/TracecatHQ/tracecat
stars: 2494
stars: 2539
owner_login: TracecatHQ
owner_html_url: https://github.com/TracecatHQ
- name: best-of-web-python
html_url: https://github.com/ml-tooling/best-of-web-python
stars: 2433
stars: 2460
owner_login: ml-tooling
owner_html_url: https://github.com/ml-tooling
- name: RasaGPT
html_url: https://github.com/paulpierre/RasaGPT
stars: 2386
stars: 2401
owner_login: paulpierre
owner_html_url: https://github.com/paulpierre
- name: fastapi-react
html_url: https://github.com/Buuntu/fastapi-react
stars: 2293
stars: 2315
owner_login: Buuntu
owner_html_url: https://github.com/Buuntu
- name: nextpy
html_url: https://github.com/dot-agent/nextpy
stars: 2256
stars: 2266
owner_login: dot-agent
owner_html_url: https://github.com/dot-agent
- name: 30-Days-of-Python
html_url: https://github.com/codingforentrepreneurs/30-Days-of-Python
stars: 2155
stars: 2163
owner_login: codingforentrepreneurs
owner_html_url: https://github.com/codingforentrepreneurs
- name: FastAPI-template
html_url: https://github.com/s3rius/FastAPI-template
stars: 2121
stars: 2156
owner_login: s3rius
owner_html_url: https://github.com/s3rius
- name: sqladmin
html_url: https://github.com/aminalaee/sqladmin
stars: 2021
stars: 2051
owner_login: aminalaee
owner_html_url: https://github.com/aminalaee
- name: langserve
html_url: https://github.com/langchain-ai/langserve
stars: 2006
stars: 2025
owner_login: langchain-ai
owner_html_url: https://github.com/langchain-ai
- name: fastapi-utils
html_url: https://github.com/fastapiutils/fastapi-utils
stars: 2002
stars: 2021
owner_login: fastapiutils
owner_html_url: https://github.com/fastapiutils
- name: solara
html_url: https://github.com/widgetti/solara
stars: 1967
stars: 1980
owner_login: widgetti
owner_html_url: https://github.com/widgetti
- name: supabase-py
html_url: https://github.com/supabase/supabase-py
stars: 1848
stars: 1874
owner_login: supabase
owner_html_url: https://github.com/supabase
- name: python-week-2022
html_url: https://github.com/rochacbruno/python-week-2022
stars: 1832
stars: 1829
owner_login: rochacbruno
owner_html_url: https://github.com/rochacbruno
- name: mangum
html_url: https://github.com/Kludex/mangum
stars: 1789
stars: 1820
owner_login: Kludex
owner_html_url: https://github.com/Kludex
- name: Kokoro-FastAPI
html_url: https://github.com/remsky/Kokoro-FastAPI
stars: 1771
owner_login: remsky
owner_html_url: https://github.com/remsky
- name: manage-fastapi
html_url: https://github.com/ycd/manage-fastapi
stars: 1711
stars: 1719
owner_login: ycd
owner_html_url: https://github.com/ycd
- name: ormar
html_url: https://github.com/collerek/ormar
stars: 1701
stars: 1710
owner_login: collerek
owner_html_url: https://github.com/collerek
- name: agentkit
html_url: https://github.com/BCG-X-Official/agentkit
stars: 1630
stars: 1658
owner_login: BCG-X-Official
owner_html_url: https://github.com/BCG-X-Official
- name: langchain-serve
html_url: https://github.com/jina-ai/langchain-serve
stars: 1617
stars: 1618
owner_login: jina-ai
owner_html_url: https://github.com/jina-ai
- name: termpair
html_url: https://github.com/cs01/termpair
stars: 1612
stars: 1611
owner_login: cs01
owner_html_url: https://github.com/cs01
- name: coronavirus-tracker-api
html_url: https://github.com/ExpDev07/coronavirus-tracker-api
stars: 1590
stars: 1588
owner_login: ExpDev07
owner_html_url: https://github.com/ExpDev07
- name: piccolo
html_url: https://github.com/piccolo-orm/piccolo
stars: 1519
stars: 1546
owner_login: piccolo-orm
owner_html_url: https://github.com/piccolo-orm
- name: fastapi-crudrouter
html_url: https://github.com/awtkns/fastapi-crudrouter
stars: 1449
owner_login: awtkns
owner_html_url: https://github.com/awtkns
- name: fastapi-cache
html_url: https://github.com/long2ice/fastapi-cache
stars: 1447
stars: 1478
owner_login: long2ice
owner_html_url: https://github.com/long2ice
- name: openapi-python-client
html_url: https://github.com/openapi-generators/openapi-python-client
stars: 1434
stars: 1467
owner_login: openapi-generators
owner_html_url: https://github.com/openapi-generators
- name: fastapi-crudrouter
html_url: https://github.com/awtkns/fastapi-crudrouter
stars: 1462
owner_login: awtkns
owner_html_url: https://github.com/awtkns
- name: awesome-fastapi-projects
html_url: https://github.com/Kludex/awesome-fastapi-projects
stars: 1398
stars: 1418
owner_login: Kludex
owner_html_url: https://github.com/Kludex
- name: awesome-python-resources
html_url: https://github.com/DjangoEx/awesome-python-resources
stars: 1380
stars: 1383
owner_login: DjangoEx
owner_html_url: https://github.com/DjangoEx
- name: slowapi
html_url: https://github.com/laurentS/slowapi
stars: 1363
owner_login: laurentS
owner_html_url: https://github.com/laurentS
- name: budgetml
html_url: https://github.com/ebhy/budgetml
stars: 1344
owner_login: ebhy
owner_html_url: https://github.com/ebhy
- name: slowapi
html_url: https://github.com/laurentS/slowapi
stars: 1339
owner_login: laurentS
owner_html_url: https://github.com/laurentS
- name: fastapi-pagination
html_url: https://github.com/uriyyo/fastapi-pagination
stars: 1263
stars: 1284
owner_login: uriyyo
owner_html_url: https://github.com/uriyyo
- name: fastapi-boilerplate
html_url: https://github.com/teamhide/fastapi-boilerplate
stars: 1206
stars: 1234
owner_login: teamhide
owner_html_url: https://github.com/teamhide
- name: fastapi-tutorial
html_url: https://github.com/liaogx/fastapi-tutorial
stars: 1178
stars: 1181
owner_login: liaogx
owner_html_url: https://github.com/liaogx
- name: fastapi-amis-admin
html_url: https://github.com/amisadmin/fastapi-amis-admin
stars: 1142
stars: 1164
owner_login: amisadmin
owner_html_url: https://github.com/amisadmin
- name: fastapi-code-generator
html_url: https://github.com/koxudaxi/fastapi-code-generator
stars: 1119
stars: 1132
owner_login: koxudaxi
owner_html_url: https://github.com/koxudaxi
- name: bolt-python
html_url: https://github.com/slackapi/bolt-python
stars: 1116
stars: 1130
owner_login: slackapi
owner_html_url: https://github.com/slackapi
- name: odmantic
html_url: https://github.com/art049/odmantic
stars: 1096
owner_login: art049
owner_html_url: https://github.com/art049
- name: langchain-extract
html_url: https://github.com/langchain-ai/langchain-extract
stars: 1093
stars: 1110
owner_login: langchain-ai
owner_html_url: https://github.com/langchain-ai
- name: odmantic
html_url: https://github.com/art049/odmantic
stars: 1104
owner_login: art049
owner_html_url: https://github.com/art049
- name: fastapi_production_template
html_url: https://github.com/zhanymkanov/fastapi_production_template
stars: 1078
stars: 1093
owner_login: zhanymkanov
owner_html_url: https://github.com/zhanymkanov
- name: SurfSense
html_url: https://github.com/MODSetter/SurfSense
stars: 1081
owner_login: MODSetter
owner_html_url: https://github.com/MODSetter
- name: fastapi-alembic-sqlmodel-async
html_url: https://github.com/jonra1993/fastapi-alembic-sqlmodel-async
stars: 1055
stars: 1063
owner_login: jonra1993
owner_html_url: https://github.com/jonra1993
- name: Kokoro-FastAPI
html_url: https://github.com/remsky/Kokoro-FastAPI
stars: 1047
owner_login: remsky
owner_html_url: https://github.com/remsky
- name: prometheus-fastapi-instrumentator
html_url: https://github.com/trallnag/prometheus-fastapi-instrumentator
stars: 1036
stars: 1059
owner_login: trallnag
owner_html_url: https://github.com/trallnag
- name: SurfSense
html_url: https://github.com/MODSetter/SurfSense
stars: 1018
owner_login: MODSetter
owner_html_url: https://github.com/MODSetter
- name: bedrock-claude-chat
html_url: https://github.com/aws-samples/bedrock-claude-chat
stars: 1010
stars: 1039
owner_login: aws-samples
owner_html_url: https://github.com/aws-samples
- name: runhouse
html_url: https://github.com/run-house/runhouse
stars: 1000
stars: 1005
owner_login: run-house
owner_html_url: https://github.com/run-house
- name: vue-fastapi-admin
html_url: https://github.com/mizhexiaoxiao/vue-fastapi-admin
stars: 987
owner_login: mizhexiaoxiao
owner_html_url: https://github.com/mizhexiaoxiao
- name: lanarky
html_url: https://github.com/ajndkr/lanarky
stars: 986
@ -370,126 +375,121 @@
owner_html_url: https://github.com/ajndkr
- name: autollm
html_url: https://github.com/viddexa/autollm
stars: 982
stars: 986
owner_login: viddexa
owner_html_url: https://github.com/viddexa
- name: restish
html_url: https://github.com/danielgtaylor/restish
stars: 970
stars: 984
owner_login: danielgtaylor
owner_html_url: https://github.com/danielgtaylor
- name: fastcrud
html_url: https://github.com/igorbenav/fastcrud
stars: 929
stars: 964
owner_login: igorbenav
owner_html_url: https://github.com/igorbenav
- name: secure
html_url: https://github.com/TypeError/secure
stars: 921
stars: 928
owner_login: TypeError
owner_html_url: https://github.com/TypeError
- name: langcorn
html_url: https://github.com/msoedov/langcorn
stars: 915
stars: 916
owner_login: msoedov
owner_html_url: https://github.com/msoedov
- name: vue-fastapi-admin
html_url: https://github.com/mizhexiaoxiao/vue-fastapi-admin
stars: 915
owner_login: mizhexiaoxiao
owner_html_url: https://github.com/mizhexiaoxiao
- name: energy-forecasting
html_url: https://github.com/iusztinpaul/energy-forecasting
stars: 891
stars: 898
owner_login: iusztinpaul
owner_html_url: https://github.com/iusztinpaul
- name: authx
html_url: https://github.com/yezz123/authx
stars: 862
stars: 874
owner_login: yezz123
owner_html_url: https://github.com/yezz123
- name: titiler
html_url: https://github.com/developmentseed/titiler
stars: 823
stars: 841
owner_login: developmentseed
owner_html_url: https://github.com/developmentseed
- name: marker-api
html_url: https://github.com/adithya-s-k/marker-api
stars: 798
owner_login: adithya-s-k
owner_html_url: https://github.com/adithya-s-k
- name: FastAPI-boilerplate
html_url: https://github.com/igorbenav/FastAPI-boilerplate
stars: 774
stars: 820
owner_login: igorbenav
owner_html_url: https://github.com/igorbenav
- name: marker-api
html_url: https://github.com/adithya-s-k/marker-api
stars: 813
owner_login: adithya-s-k
owner_html_url: https://github.com/adithya-s-k
- name: fastapi_best_architecture
html_url: https://github.com/fastapi-practices/fastapi_best_architecture
stars: 766
stars: 802
owner_login: fastapi-practices
owner_html_url: https://github.com/fastapi-practices
- name: fastapi-mail
html_url: https://github.com/sabuhish/fastapi-mail
stars: 735
owner_login: sabuhish
owner_html_url: https://github.com/sabuhish
- name: annotated-py-projects
html_url: https://github.com/hhstore/annotated-py-projects
stars: 725
owner_login: hhstore
owner_html_url: https://github.com/hhstore
- name: fastapi-do-zero
html_url: https://github.com/dunossauro/fastapi-do-zero
stars: 723
stars: 745
owner_login: dunossauro
owner_html_url: https://github.com/dunossauro
- name: lccn_predictor
html_url: https://github.com/baoliay2008/lccn_predictor
stars: 718
owner_login: baoliay2008
owner_html_url: https://github.com/baoliay2008
- name: fastapi-mail
html_url: https://github.com/sabuhish/fastapi-mail
stars: 744
owner_login: sabuhish
owner_html_url: https://github.com/sabuhish
- name: fastapi-observability
html_url: https://github.com/blueswen/fastapi-observability
stars: 718
stars: 743
owner_login: blueswen
owner_html_url: https://github.com/blueswen
- name: chatGPT-web
html_url: https://github.com/mic1on/chatGPT-web
stars: 708
owner_login: mic1on
owner_html_url: https://github.com/mic1on
- name: lccn_predictor
html_url: https://github.com/baoliay2008/lccn_predictor
stars: 741
owner_login: baoliay2008
owner_html_url: https://github.com/baoliay2008
- name: annotated-py-projects
html_url: https://github.com/hhstore/annotated-py-projects
stars: 727
owner_login: hhstore
owner_html_url: https://github.com/hhstore
- name: learn-generative-ai
html_url: https://github.com/panaverse/learn-generative-ai
stars: 701
stars: 714
owner_login: panaverse
owner_html_url: https://github.com/panaverse
- name: linbing
html_url: https://github.com/taomujian/linbing
stars: 700
owner_login: taomujian
owner_html_url: https://github.com/taomujian
- name: FastAPI-Backend-Template
html_url: https://github.com/Aeternalis-Ingenium/FastAPI-Backend-Template
stars: 692
owner_login: Aeternalis-Ingenium
owner_html_url: https://github.com/Aeternalis-Ingenium
- name: starlette-admin
html_url: https://github.com/jowilf/starlette-admin
stars: 692
stars: 713
owner_login: jowilf
owner_html_url: https://github.com/jowilf
- name: chatGPT-web
html_url: https://github.com/mic1on/chatGPT-web
stars: 712
owner_login: mic1on
owner_html_url: https://github.com/mic1on
- name: FastAPI-Backend-Template
html_url: https://github.com/Aeternalis-Ingenium/FastAPI-Backend-Template
stars: 709
owner_login: Aeternalis-Ingenium
owner_html_url: https://github.com/Aeternalis-Ingenium
- name: linbing
html_url: https://github.com/taomujian/linbing
stars: 698
owner_login: taomujian
owner_html_url: https://github.com/taomujian
- name: KonomiTV
html_url: https://github.com/tsukumijima/KonomiTV
stars: 687
owner_login: tsukumijima
owner_html_url: https://github.com/tsukumijima
- name: fastapi-jwt-auth
html_url: https://github.com/IndominusByte/fastapi-jwt-auth
stars: 674
stars: 685
owner_login: IndominusByte
owner_html_url: https://github.com/IndominusByte
- name: pity
html_url: https://github.com/wuranxu/pity
stars: 663
stars: 667
owner_login: wuranxu
owner_html_url: https://github.com/wuranxu
- name: fastapi_login
html_url: https://github.com/MushroomMaula/fastapi_login
stars: 656
owner_login: MushroomMaula
owner_html_url: https://github.com/MushroomMaula

199
docs/en/data/translation_reviewers.yml

@ -10,9 +10,14 @@ Xewus:
url: https://github.com/Xewus
ceb10n:
login: ceb10n
count: 110
count: 112
avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
url: https://github.com/ceb10n
sodaMelon:
login: sodaMelon
count: 111
avatarUrl: https://avatars.githubusercontent.com/u/66295123?u=be939db90f1119efee9e6110cc05066ff1f40f00&v=4
url: https://github.com/sodaMelon
tokusumi:
login: tokusumi
count: 104
@ -28,31 +33,26 @@ hard-coders:
count: 92
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
url: https://github.com/hard-coders
nazarepiedady:
login: nazarepiedady
count: 83
avatarUrl: https://avatars.githubusercontent.com/u/31008635?u=8dc25777dc9cb51fb0dbba2f137988953d330b78&v=4
url: https://github.com/nazarepiedady
AlertRED:
login: AlertRED
count: 81
avatarUrl: https://avatars.githubusercontent.com/u/15695000?u=f5a4944c6df443030409c88da7d7fa0b7ead985c&v=4
url: https://github.com/AlertRED
nazarepiedady:
login: nazarepiedady
count: 81
avatarUrl: https://avatars.githubusercontent.com/u/31008635?u=8dc25777dc9cb51fb0dbba2f137988953d330b78&v=4
url: https://github.com/nazarepiedady
sodaMelon:
login: sodaMelon
alv2017:
login: alv2017
count: 81
avatarUrl: https://avatars.githubusercontent.com/u/66295123?u=be939db90f1119efee9e6110cc05066ff1f40f00&v=4
url: https://github.com/sodaMelon
avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
url: https://github.com/alv2017
Alexandrhub:
login: Alexandrhub
count: 68
avatarUrl: https://avatars.githubusercontent.com/u/119126536?u=9fc0d48f3307817bafecc5861eb2168401a6cb04&v=4
url: https://github.com/Alexandrhub
alv2017:
login: alv2017
count: 64
avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
url: https://github.com/alv2017
waynerv:
login: waynerv
count: 63
@ -68,6 +68,11 @@ mattwang44:
count: 58
avatarUrl: https://avatars.githubusercontent.com/u/24987826?u=58e37fb3927b9124b458945ac4c97aa0f1062d85&v=4
url: https://github.com/mattwang44
tiangolo:
login: tiangolo
count: 51
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
url: https://github.com/tiangolo
Laineyzhang55:
login: Laineyzhang55
count: 48
@ -88,11 +93,11 @@ alperiox:
count: 42
avatarUrl: https://avatars.githubusercontent.com/u/34214152?u=2c5acad3461d4dbc2d48371ba86cac56ae9b25cc&v=4
url: https://github.com/alperiox
tiangolo:
login: tiangolo
count: 40
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
url: https://github.com/tiangolo
rostik1410:
login: rostik1410
count: 41
avatarUrl: https://avatars.githubusercontent.com/u/11443899?u=e26a635c2ba220467b308a326a579b8ccf4a8701&v=4
url: https://github.com/rostik1410
Winand:
login: Winand
count: 40
@ -118,11 +123,31 @@ SwftAlpc:
count: 36
avatarUrl: https://avatars.githubusercontent.com/u/52768429?u=6a3aa15277406520ad37f6236e89466ed44bc5b8&v=4
url: https://github.com/SwftAlpc
alejsdev:
login: alejsdev
count: 36
avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=356f39ff3f0211c720b06d3dbb060e98884085e3&v=4
url: https://github.com/alejsdev
timothy-jeong:
login: timothy-jeong
count: 36
avatarUrl: https://avatars.githubusercontent.com/u/53824764?u=db3d0cea2f5fab64d810113c5039a369699a2774&v=4
url: https://github.com/timothy-jeong
nilslindemann:
login: nilslindemann
count: 35
avatarUrl: https://avatars.githubusercontent.com/u/6892179?u=1dca6a22195d6cd1ab20737c0e19a4c55d639472&v=4
url: https://github.com/nilslindemann
svlandeg:
login: svlandeg
count: 35
avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4
url: https://github.com/svlandeg
Rishat-F:
login: Rishat-F
count: 35
avatarUrl: https://avatars.githubusercontent.com/u/66554797?v=4
url: https://github.com/Rishat-F
rjNemo:
login: rjNemo
count: 34
@ -143,11 +168,6 @@ romashevchenko:
count: 32
avatarUrl: https://avatars.githubusercontent.com/u/132477732?v=4
url: https://github.com/romashevchenko
alejsdev:
login: alejsdev
count: 32
avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=356f39ff3f0211c720b06d3dbb060e98884085e3&v=4
url: https://github.com/alejsdev
wdh99:
login: wdh99
count: 31
@ -208,6 +228,11 @@ junah201:
count: 26
avatarUrl: https://avatars.githubusercontent.com/u/75025529?u=2451c256e888fa2a06bcfc0646d09b87ddb6a945&v=4
url: https://github.com/junah201
mezgoodle:
login: mezgoodle
count: 26
avatarUrl: https://avatars.githubusercontent.com/u/41520940?u=e871bc26734eb2436d98c19c3fb57a4773e13c24&v=4
url: https://github.com/mezgoodle
Vincy1230:
login: Vincy1230
count: 26
@ -248,11 +273,6 @@ wisderfin:
count: 23
avatarUrl: https://avatars.githubusercontent.com/u/77553770?u=f3b00a26736ba664e9927a1116c6e8088295e073&v=4
url: https://github.com/wisderfin
rostik1410:
login: rostik1410
count: 22
avatarUrl: https://avatars.githubusercontent.com/u/11443899?u=e26a635c2ba220467b308a326a579b8ccf4a8701&v=4
url: https://github.com/rostik1410
AGolicyn:
login: AGolicyn
count: 21
@ -266,7 +286,7 @@ Attsun1031:
ycd:
login: ycd
count: 20
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=29682e4b6ac7d5293742ccf818188394b9a82972&v=4
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=f1e7bae394a315da950912c92dc861a8eaf95d4c&v=4
url: https://github.com/ycd
delhi09:
login: delhi09
@ -283,26 +303,21 @@ DevDae:
count: 20
avatarUrl: https://avatars.githubusercontent.com/u/87962045?u=08e10fa516e844934f4b3fc7c38b33c61697e4a1&v=4
url: https://github.com/DevDae
svlandeg:
login: svlandeg
count: 20
avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4
url: https://github.com/svlandeg
sattosan:
login: sattosan
count: 19
avatarUrl: https://avatars.githubusercontent.com/u/20574756?u=b0d8474d2938189c6954423ae8d81d91013f80a8&v=4
url: https://github.com/sattosan
yes0ng:
login: yes0ng
count: 19
avatarUrl: https://avatars.githubusercontent.com/u/25501794?u=3aed18b0d491e0220a167a1e9e58bea3638c6707&v=4
url: https://github.com/yes0ng
ComicShrimp:
login: ComicShrimp
count: 18
avatarUrl: https://avatars.githubusercontent.com/u/43503750?u=d2fbf412e7730183ce91686ca48d4147e1b7dc74&v=4
url: https://github.com/ComicShrimp
mezgoodle:
login: mezgoodle
count: 18
avatarUrl: https://avatars.githubusercontent.com/u/41520940?u=e871bc26734eb2436d98c19c3fb57a4773e13c24&v=4
url: https://github.com/mezgoodle
simatheone:
login: simatheone
count: 18
@ -473,11 +488,6 @@ kwang1215:
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/74170199?u=2a63ff6692119dde3f5e5693365b9fcd6f977b08&v=4
url: https://github.com/kwang1215
Rishat-F:
login: Rishat-F
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/66554797?v=4
url: https://github.com/Rishat-F
AdrianDeAnda:
login: AdrianDeAnda
count: 11
@ -498,6 +508,11 @@ glsglsgls:
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/76133879?v=4
url: https://github.com/glsglsgls
k94-ishi:
login: k94-ishi
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/32672580?u=bc7c5c07af0656be9fe4f1784a444af8d81ded89&v=4
url: https://github.com/k94-ishi
codespearhead:
login: codespearhead
count: 11
@ -586,7 +601,7 @@ waketzheng:
lucasbalieiro:
login: lucasbalieiro
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/37416577?u=5a395a69384e7fa0f9840ea32ef963d3f1cd9da4&v=4
avatarUrl: https://avatars.githubusercontent.com/u/37416577?u=eabaf4aebbaa88a94a4886273edba689012cee70&v=4
url: https://github.com/lucasbalieiro
RunningIkkyu:
login: RunningIkkyu
@ -648,6 +663,11 @@ Zhongheng-Cheng:
count: 9
avatarUrl: https://avatars.githubusercontent.com/u/95612344?u=a0f7730a3cc7486827965e01a119ad610bda4b0a&v=4
url: https://github.com/Zhongheng-Cheng
Yarous:
login: Yarous
count: 9
avatarUrl: https://avatars.githubusercontent.com/u/61277193?u=5b462347458a373b2d599c6f416d2b75eddbffad&v=4
url: https://github.com/Yarous
dimaqq:
login: dimaqq
count: 8
@ -683,11 +703,21 @@ KimJoonSeo:
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/17760162?u=a58cdc77ae1c069a64166f7ecc4d42eecfd9a468&v=4
url: https://github.com/KimJoonSeo
MinLee0210:
login: MinLee0210
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/57653278?u=7def7c0654ad82f43b46d6dfc3b51c4d2be15011&v=4
url: https://github.com/MinLee0210
camigomezdev:
login: camigomezdev
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/16061815?u=25b5ebc042fff53fa03dc107ded10e36b1b7a5b9&v=4
url: https://github.com/camigomezdev
maru0123-2004:
login: maru0123-2004
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/43961566?u=16ed8603a4d6a4665cb6c53a7aece6f31379b769&v=4
url: https://github.com/maru0123-2004
Serrones:
login: Serrones
count: 7
@ -843,6 +873,16 @@ bankofsardine:
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/44944207?u=0368e1b698ffab6bf29e202f9fd2dddd352429f1&v=4
url: https://github.com/bankofsardine
SofiiaTrufanova:
login: SofiiaTrufanova
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/63260929?v=4
url: https://github.com/SofiiaTrufanova
DianaTrufanova:
login: DianaTrufanova
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/119067607?v=4
url: https://github.com/DianaTrufanova
rsip22:
login: rsip22
count: 5
@ -856,7 +896,7 @@ jessicapaz:
mohsen-mahmoodi:
login: mohsen-mahmoodi
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/2872586?u=9274b3b13d8a992dba29b162fee48473a0fa142d&v=4
avatarUrl: https://avatars.githubusercontent.com/u/2872586?u=3a9fc1aa16a3a0ab93a1f8550de82a940592857d&v=4
url: https://github.com/mohsen-mahmoodi
jeesang7:
login: jeesang7
@ -958,11 +998,11 @@ devluisrodrigues:
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/103431660?u=d9674a3249edc4601d2c712cdebf899918503c3a&v=4
url: https://github.com/devluisrodrigues
timothy-jeong:
login: timothy-jeong
11kkw:
login: 11kkw
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/53824764?u=db3d0cea2f5fab64d810113c5039a369699a2774&v=4
url: https://github.com/timothy-jeong
avatarUrl: https://avatars.githubusercontent.com/u/21125286?v=4
url: https://github.com/11kkw
lpdswing:
login: lpdswing
count: 4
@ -976,7 +1016,7 @@ SepehrRasouli:
Zxilly:
login: Zxilly
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/31370133?u=122e23d6e974614736be606e4ea816f45e7745f8&v=4
avatarUrl: https://avatars.githubusercontent.com/u/31370133?u=c5359b8d9d80a7cdc23d5295d179ed90174996c8&v=4
url: https://github.com/Zxilly
eavv:
login: eavv
@ -1016,7 +1056,7 @@ personage-hub:
aminalaee:
login: aminalaee
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/19784933?u=2f45a312b73e7fb29f3b6f8676e5be6f7220da25&v=4
avatarUrl: https://avatars.githubusercontent.com/u/19784933?v=4
url: https://github.com/aminalaee
erfan-rfmhr:
login: erfan-rfmhr
@ -1058,11 +1098,11 @@ matiasbertani:
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/65260383?u=d5edd86a6e2ab4fb1aab7751931fe045a963afd7&v=4
url: https://github.com/matiasbertani
k94-ishi:
login: k94-ishi
thiennc254:
login: thiennc254
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/32672580?u=bc7c5c07af0656be9fe4f1784a444af8d81ded89&v=4
url: https://github.com/k94-ishi
avatarUrl: https://avatars.githubusercontent.com/u/97406628?u=1b2860679694b9a552764d0fa81dbd7a016322ec&v=4
url: https://github.com/thiennc254
javillegasna:
login: javillegasna
count: 4
@ -1078,11 +1118,16 @@ ilhamfadillah:
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/20577838?u=c56192cf99b55affcaad408b240259c62e633450&v=4
url: https://github.com/ilhamfadillah
Yarous:
login: Yarous
gerry-sabar:
login: gerry-sabar
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/61277193?u=5b462347458a373b2d599c6f416d2b75eddbffad&v=4
url: https://github.com/Yarous
avatarUrl: https://avatars.githubusercontent.com/u/1120123?v=4
url: https://github.com/gerry-sabar
valentinDruzhinin:
login: valentinDruzhinin
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/12831905?u=aae1ebc675c91e8fa582df4fcc4fc4128106344d&v=4
url: https://github.com/valentinDruzhinin
tyronedamasceno:
login: tyronedamasceno
count: 3
@ -1308,11 +1353,16 @@ RyaWcksn:
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/42831964?u=0cb4265faf3e3425a89e59b6fddd3eb2de180af0&v=4
url: https://github.com/RyaWcksn
gerry-sabar:
login: gerry-sabar
Zerohertz:
login: Zerohertz
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/1120123?v=4
url: https://github.com/gerry-sabar
avatarUrl: https://avatars.githubusercontent.com/u/42334717?u=c6acda352c866b1747921e0ff8782b58571d849e&v=4
url: https://github.com/Zerohertz
tienduong-21:
login: tienduong-21
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/80129618?v=4
url: https://github.com/tienduong-21
blaisep:
login: blaisep
count: 2
@ -1471,7 +1521,7 @@ felipebpl:
iudeen:
login: iudeen
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4
avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=f09cdd745e5bf16138f29b42732dd57c7f02bee1&v=4
url: https://github.com/iudeen
dwisulfahnur:
login: dwisulfahnur
@ -1623,6 +1673,16 @@ UN-9BOT:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/111110804?u=39e158937ed795972c2d0400fc521c50e9bfb9e7&v=4
url: https://github.com/UN-9BOT
flasonme:
login: flasonme
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/30571019?v=4
url: https://github.com/flasonme
ptt3199:
login: ptt3199
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/51350651?u=ccf51f8820787e17983954f26b06acf226cba293&v=4
url: https://github.com/ptt3199
gustavoprezoto:
login: gustavoprezoto
count: 2
@ -1668,3 +1728,8 @@ kiharito:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/38311245?v=4
url: https://github.com/kiharito
J-Fuji:
login: J-Fuji
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/101452903?v=4
url: https://github.com/J-Fuji

56
docs/en/data/translators.yml

@ -10,7 +10,7 @@ jaystone776:
url: https://github.com/jaystone776
ceb10n:
login: ceb10n
count: 26
count: 27
avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
url: https://github.com/ceb10n
tokusumi:
@ -43,21 +43,26 @@ 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
avatarUrl: https://avatars.githubusercontent.com/u/110267046?u=331bd016326dac4cf3df4848f6db2dbbf8b5f978&v=4
url: https://github.com/Joao-Pedro-P-Holanda
codingjenny:
login: codingjenny
count: 14
avatarUrl: https://avatars.githubusercontent.com/u/103817302?u=3a042740dc0ff58615da0d8679230966fd7693e8&v=4
url: https://github.com/codingjenny
valentinDruzhinin:
login: valentinDruzhinin
count: 14
avatarUrl: https://avatars.githubusercontent.com/u/12831905?u=aae1ebc675c91e8fa582df4fcc4fc4128106344d&v=4
url: https://github.com/valentinDruzhinin
Xewus:
login: Xewus
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/85196001?u=f8e2dc7e5104f109cef944af79050ea8d1b8f914&v=4
url: https://github.com/Xewus
Joao-Pedro-P-Holanda:
login: Joao-Pedro-P-Holanda
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/110267046?u=331bd016326dac4cf3df4848f6db2dbbf8b5f978&v=4
url: https://github.com/Joao-Pedro-P-Holanda
Smlep:
login: Smlep
count: 11
@ -106,13 +111,18 @@ batlopes:
lucasbalieiro:
login: lucasbalieiro
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/37416577?u=5a395a69384e7fa0f9840ea32ef963d3f1cd9da4&v=4
avatarUrl: https://avatars.githubusercontent.com/u/37416577?u=eabaf4aebbaa88a94a4886273edba689012cee70&v=4
url: https://github.com/lucasbalieiro
Alexandrhub:
login: Alexandrhub
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/119126536?u=9fc0d48f3307817bafecc5861eb2168401a6cb04&v=4
url: https://github.com/Alexandrhub
ptt3199:
login: ptt3199
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/51350651?u=ccf51f8820787e17983954f26b06acf226cba293&v=4
url: https://github.com/ptt3199
Serrones:
login: Serrones
count: 5
@ -143,6 +153,11 @@ rostik1410:
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/11443899?u=e26a635c2ba220467b308a326a579b8ccf4a8701&v=4
url: https://github.com/rostik1410
alv2017:
login: alv2017
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
url: https://github.com/alv2017
komtaki:
login: komtaki
count: 4
@ -188,11 +203,6 @@ kwang1215:
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/74170199?u=2a63ff6692119dde3f5e5693365b9fcd6f977b08&v=4
url: https://github.com/kwang1215
alv2017:
login: alv2017
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
url: https://github.com/alv2017
jfunez:
login: jfunez
count: 3
@ -201,7 +211,7 @@ jfunez:
ycd:
login: ycd
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=29682e4b6ac7d5293742ccf818188394b9a82972&v=4
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=f1e7bae394a315da950912c92dc861a8eaf95d4c&v=4
url: https://github.com/ycd
mariacamilagl:
login: mariacamilagl
@ -323,6 +333,16 @@ gerry-sabar:
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/1120123?v=4
url: https://github.com/gerry-sabar
k94-ishi:
login: k94-ishi
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/32672580?u=bc7c5c07af0656be9fe4f1784a444af8d81ded89&v=4
url: https://github.com/k94-ishi
Rishat-F:
login: Rishat-F
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/66554797?v=4
url: https://github.com/Rishat-F
izaguerreiro:
login: izaguerreiro
count: 2
@ -451,7 +471,7 @@ choi-haram:
imtiaz101325:
login: imtiaz101325
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/54007087?u=7a210ee38a0a30b7536226419b3b799620ad57d9&v=4
avatarUrl: https://avatars.githubusercontent.com/u/54007087?u=194d972b501b9ea9d2ddeaed757c492936e0121a&v=4
url: https://github.com/imtiaz101325
waketzheng:
login: waketzheng
@ -488,8 +508,8 @@ timothy-jeong:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/53824764?u=db3d0cea2f5fab64d810113c5039a369699a2774&v=4
url: https://github.com/timothy-jeong
Rishat-F:
login: Rishat-F
11kkw:
login: 11kkw
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/66554797?v=4
url: https://github.com/Rishat-F
avatarUrl: https://avatars.githubusercontent.com/u/21125286?v=4
url: https://github.com/11kkw

15
docs/en/docs/advanced/index.md

@ -19,18 +19,3 @@ And it's possible that for your use case, the solution is in one of them.
You could still use most of the features in **FastAPI** with the knowledge from the main [Tutorial - User Guide](../tutorial/index.md){.internal-link target=_blank}.
And the next sections assume you already read it, and assume that you know those main ideas.
## External Courses
Although the [Tutorial - User Guide](../tutorial/index.md){.internal-link target=_blank} and this **Advanced User Guide** are written as a guided tutorial (like a book) and should be enough for you to **learn FastAPI**, you might want to complement it with additional courses.
Or it might be the case that you just prefer to take other courses because they adapt better to your learning style.
Some course providers ✨ [**sponsor FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, this ensures the continued and healthy **development** of FastAPI and its **ecosystem**.
And it shows their true commitment to FastAPI and its **community** (you), as they not only want to provide you a **good learning experience** but also want to make sure you have a **good and healthy framework**, FastAPI. 🙇
You might want to try their courses:
* <a href="https://training.talkpython.fm/fastapi-courses" class="external-link" target="_blank">Talk Python Training</a>
* <a href="https://testdriven.io/courses/tdd-fastapi/" class="external-link" target="_blank">Test-Driven Development</a>

BIN
docs/en/docs/img/sponsors/coderabbit-banner.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

BIN
docs/en/docs/img/sponsors/coderabbit.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
docs/en/docs/img/sponsors/lambdatest.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

88
docs/en/docs/release-notes.md

@ -7,12 +7,94 @@ hide:
## Latest Changes
### Translations
* 🌐 Add Korean translation for `docs/ko/docs/tutorial/security/oauth2-jwt.md`. PR [#13333](https://github.com/fastapi/fastapi/pull/13333) by [@yes0ng](https://github.com/yes0ng).
* 🌐 Add Vietnamese translation for `docs/vi/docs/deployment/cloud.md`. PR [#13407](https://github.com/fastapi/fastapi/pull/13407) by [@ptt3199](https://github.com/ptt3199).
### Internal
* ⬆ Bump sqlmodel from 0.0.22 to 0.0.23. PR [#13437](https://github.com/fastapi/fastapi/pull/13437) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump black from 24.10.0 to 25.1.0. PR [#13436](https://github.com/fastapi/fastapi/pull/13436) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff to 0.9.4. PR [#13299](https://github.com/fastapi/fastapi/pull/13299) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 🔧 Update sponsors: pause TestDriven. PR [#13446](https://github.com/fastapi/fastapi/pull/13446) by [@tiangolo](https://github.com/tiangolo).
## 0.115.11
### Fixes
* 🐛 Add docs examples and tests (support) for `Annotated` custom validations, like `AfterValidator`, revert [#13440](https://github.com/fastapi/fastapi/pull/13440). PR [#13442](https://github.com/fastapi/fastapi/pull/13442) by [@tiangolo](https://github.com/tiangolo).
* New docs: [Query Parameters and String Validations - Custom Validation](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#custom-validation).
### Translations
* 🌐 Add Russian translation for `docs/ru/docs/tutorial/middleware.md`. PR [#13412](https://github.com/fastapi/fastapi/pull/13412) by [@alv2017](https://github.com/alv2017).
### Internal
* 👥 Update FastAPI GitHub topic repositories. PR [#13439](https://github.com/fastapi/fastapi/pull/13439) by [@tiangolo](https://github.com/tiangolo).
* 👥 Update FastAPI People - Contributors and Translators. PR [#13432](https://github.com/fastapi/fastapi/pull/13432) by [@tiangolo](https://github.com/tiangolo).
* 👥 Update FastAPI People - Sponsors. PR [#13433](https://github.com/fastapi/fastapi/pull/13433) by [@tiangolo](https://github.com/tiangolo).
## 0.115.10
### Fixes
* ♻️ Update internal annotation usage for compatibility with Pydantic 2.11. PR [#13314](https://github.com/fastapi/fastapi/pull/13314) by [@Viicos](https://github.com/Viicos).
### Upgrades
* ⬆️ Bump Starlette to allow up to 0.46.0: `>=0.40.0,<0.47.0`. PR [#13426](https://github.com/fastapi/fastapi/pull/13426) by [@musicinmybrain](https://github.com/musicinmybrain).
### Translations
* 🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/debugging.md`. PR [#13370](https://github.com/fastapi/fastapi/pull/13370) by [@valentinDruzhinin](https://github.com/valentinDruzhinin).
* 🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/query-params.md`. PR [#13362](https://github.com/fastapi/fastapi/pull/13362) by [@valentinDruzhinin](https://github.com/valentinDruzhinin).
* 🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/path-params.md`. PR [#13354](https://github.com/fastapi/fastapi/pull/13354) by [@valentinDruzhinin](https://github.com/valentinDruzhinin).
* 🌐 Add Japanese translation for `docs/ja/docs/tutorial/cookie-param-models.md`. PR [#13330](https://github.com/fastapi/fastapi/pull/13330) by [@k94-ishi](https://github.com/k94-ishi).
* 🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/body-multiple-params.md`. PR [#13408](https://github.com/fastapi/fastapi/pull/13408) by [@valentinDruzhinin](https://github.com/valentinDruzhinin).
* 🌐 Add Japanese translation for `docs/ja/docs/tutorial/query-param-models.md`. PR [#13323](https://github.com/fastapi/fastapi/pull/13323) by [@k94-ishi](https://github.com/k94-ishi).
* 🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/body-nested-models.md`. PR [#13409](https://github.com/fastapi/fastapi/pull/13409) by [@valentinDruzhinin](https://github.com/valentinDruzhinin).
* 🌐 Add Vietnamese translation for `docs/vi/docs/deployment/versions.md`. PR [#13406](https://github.com/fastapi/fastapi/pull/13406) by [@ptt3199](https://github.com/ptt3199).
* 🌐 Add Vietnamese translation for `docs/vi/docs/deployment/index.md`. PR [#13405](https://github.com/fastapi/fastapi/pull/13405) by [@ptt3199](https://github.com/ptt3199).
* 🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/request-forms.md`. PR [#13383](https://github.com/fastapi/fastapi/pull/13383) by [@valentinDruzhinin](https://github.com/valentinDruzhinin).
* 🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/testing.md`. PR [#13371](https://github.com/fastapi/fastapi/pull/13371) by [@valentinDruzhinin](https://github.com/valentinDruzhinin).
## 0.115.9
### Fixes
* 🐛 Ensure that `HTTPDigest` only raises an exception when `auto_error is True`. PR [#2939](https://github.com/fastapi/fastapi/pull/2939) by [@arthurio](https://github.com/arthurio).
### Refactors
* ✅ Simplify tests for `query_params_str_validations`. PR [#13218](https://github.com/fastapi/fastapi/pull/13218) by [@alv2017](https://github.com/alv2017).
* ✅ Simplify tests for `app_testing`. PR [#13220](https://github.com/fastapi/fastapi/pull/13220) by [@alv2017](https://github.com/alv2017).
* ✅ Simplify tests for `dependency_testing`. PR [#13223](https://github.com/fastapi/fastapi/pull/13223) by [@alv2017](https://github.com/alv2017).
### Docs
* 🍱 Update sponsors: CodeRabbit logo. PR [#13424](https://github.com/fastapi/fastapi/pull/13424) by [@tiangolo](https://github.com/tiangolo).
* 🩺 Unify the badges across all tutorial translations. PR [#13329](https://github.com/fastapi/fastapi/pull/13329) by [@svlandeg](https://github.com/svlandeg).
* 📝 Fix typos in virtual environments documentation. PR [#13396](https://github.com/fastapi/fastapi/pull/13396) by [@bullet-ant](https://github.com/bullet-ant).
* 🐛 Fix issue with Swagger theme change example in the official tutorial. PR [#13289](https://github.com/fastapi/fastapi/pull/13289) by [@Zerohertz](https://github.com/Zerohertz).
* 📝 Add more precise description of HTTP status code range in docs. PR [#13347](https://github.com/fastapi/fastapi/pull/13347) by [@DanielYang59](https://github.com/DanielYang59).
* 🔥 Remove manual type annotations in JWT tutorial to avoid typing expectations (JWT doesn't provide more types). PR [#13378](https://github.com/fastapi/fastapi/pull/13378) by [@tiangolo](https://github.com/tiangolo).
* 📝 Update docs for Query Params and String Validations, remove obsolete Ellipsis docs (`...`). PR [#13377](https://github.com/fastapi/fastapi/pull/13377) by [@tiangolo](https://github.com/tiangolo).
* ✏️ Remove duplicate title in docs `body-multiple-params`. PR [#13345](https://github.com/fastapi/fastapi/pull/13345) by [@DanielYang59](https://github.com/DanielYang59).
* 📝 Fix test badge. PR [#13313](https://github.com/fastapi/fastapi/pull/13313) by [@esadek](https://github.com/esadek).
### Translations
* 🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/header-params.md`. PR [#13381](https://github.com/fastapi/fastapi/pull/13381) by [@valentinDruzhinin](https://github.com/valentinDruzhinin).
* 🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/request-files.md`. PR [#13395](https://github.com/fastapi/fastapi/pull/13395) by [@valentinDruzhinin](https://github.com/valentinDruzhinin).
* 🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/request-form-models.md`. PR [#13384](https://github.com/fastapi/fastapi/pull/13384) by [@valentinDruzhinin](https://github.com/valentinDruzhinin).
* 🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/request-forms-and-files.md`. PR [#13386](https://github.com/fastapi/fastapi/pull/13386) by [@valentinDruzhinin](https://github.com/valentinDruzhinin).
* 🌐 Update Korean translation for `docs/ko/docs/help-fastapi.md`. PR [#13262](https://github.com/fastapi/fastapi/pull/13262) by [@Zerohertz](https://github.com/Zerohertz).
* 🌐 Add Korean translation for `docs/ko/docs/advanced/custom-response.md`. PR [#13265](https://github.com/fastapi/fastapi/pull/13265) by [@11kkw](https://github.com/11kkw).
* 🌐 Update Korean translation for `docs/ko/docs/tutorial/security/simple-oauth2.md`. PR [#13335](https://github.com/fastapi/fastapi/pull/13335) by [@yes0ng](https://github.com/yes0ng).
* 🌐 Add Russian translation for `docs/ru/docs/advanced/response-cookies.md`. PR [#13327](https://github.com/fastapi/fastapi/pull/13327) by [@Stepakinoyan](https://github.com/Stepakinoyan).
* 🌐 Add Vietnamese translation for `docs/vi/docs/tutorial/static-files.md`. PR [#11291](https://github.com/fastapi/fastapi/pull/11291) by [@ptt3199](https://github.com/ptt3199).
* 🌐 Add Korean translation for `docs/ko/docs/tutorial/dependencies/dependencies-with-yield.md`. PR [#13257](https://github.com/fastapi/fastapi/pull/13257) by [@11kkw](https://github.com/11kkw).
* 🌐 Add Vietnamese translation for `docs/vi/docs/virtual-environments.md`. PR [#13282](https://github.com/fastapi/fastapi/pull/13282) by [@ptt3199](https://github.com/ptt3199).
* 🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/static-files.md`. PR [#13285](https://github.com/fastapi/fastapi/pull/13285) by [@valentinDruzhinin](https://github.com/valentinDruzhinin).
@ -26,6 +108,12 @@ hide:
### Internal
* ✅ Fix a minor bug in the test `tests/test_modules_same_name_body/test_main.py`. PR [#13411](https://github.com/fastapi/fastapi/pull/13411) by [@alv2017](https://github.com/alv2017).
* 👷 Use `wrangler-action` v3. PR [#13415](https://github.com/fastapi/fastapi/pull/13415) by [@joakimnordling](https://github.com/joakimnordling).
* 🔧 Update sponsors: add CodeRabbit. PR [#13402](https://github.com/fastapi/fastapi/pull/13402) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Update team: Add Ludovico. PR [#13390](https://github.com/fastapi/fastapi/pull/13390) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Update sponsors: Add LambdaTest. PR [#13389](https://github.com/fastapi/fastapi/pull/13389) by [@tiangolo](https://github.com/tiangolo).
* ⬆ Bump cloudflare/wrangler-action from 3.13 to 3.14. PR [#13350](https://github.com/fastapi/fastapi/pull/13350) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump mkdocs-material from 9.5.18 to 9.6.1. PR [#13301](https://github.com/fastapi/fastapi/pull/13301) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump pillow from 11.0.0 to 11.1.0. PR [#13300](https://github.com/fastapi/fastapi/pull/13300) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 👥 Update FastAPI People - Sponsors. PR [#13295](https://github.com/fastapi/fastapi/pull/13295) by [@tiangolo](https://github.com/tiangolo).

2
docs/en/docs/tutorial/body-multiple-params.md

@ -10,8 +10,6 @@ And you can also declare body parameters as optional, by setting the default to
{* ../../docs_src/body_multiple_params/tutorial001_an_py310.py hl[18:20] *}
## Multiple body parameters
/// note
Notice that, in this case, the `item` that would be taken from the body is optional. As it has a `None` default value.

181
docs/en/docs/tutorial/query-params-str-validations.md

@ -6,13 +6,13 @@ Let's take this application as example:
{* ../../docs_src/query_params_str_validations/tutorial001_py310.py hl[7] *}
The query parameter `q` is of type `Union[str, None]` (or `str | None` in Python 3.10), that means that it's of type `str` but could also be `None`, and indeed, the default value is `None`, so FastAPI will know it's not required.
The query parameter `q` is of type `str | None`, that means that it's of type `str` but could also be `None`, and indeed, the default value is `None`, so FastAPI will know it's not required.
/// note
FastAPI will know that the value of `q` is not required because of the default value `= None`.
The `Union` in `Union[str, None]` will allow your editor to give you better support and detect errors.
Having `str | None` will allow your editor to give you better support and detect errors.
///
@ -25,29 +25,9 @@ We are going to enforce that even though `q` is optional, whenever it is provide
To achieve that, first import:
* `Query` from `fastapi`
* `Annotated` from `typing` (or from `typing_extensions` in Python below 3.9)
* `Annotated` from `typing`
//// tab | Python 3.10+
In Python 3.9 or above, `Annotated` is part of the standard library, so you can import it from `typing`.
```Python hl_lines="1 3"
{!> ../../docs_src/query_params_str_validations/tutorial002_an_py310.py!}
```
////
//// tab | Python 3.8+
In versions of Python below Python 3.9 you import `Annotated` from `typing_extensions`.
It will already be installed with FastAPI.
```Python hl_lines="3-4"
{!> ../../docs_src/query_params_str_validations/tutorial002_an.py!}
```
////
{* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[1,3] *}
/// info
@ -145,54 +125,23 @@ As in this case (without using `Annotated`) we have to replace the default value
So:
```Python
q: Union[str, None] = Query(default=None)
```
...makes the parameter optional, with a default value of `None`, the same as:
```Python
q: Union[str, None] = None
```
And in Python 3.10 and above:
```Python
q: str | None = Query(default=None)
```
...makes the parameter optional, with a default value of `None`, the same as:
```Python
q: str | None = None
```
But the `Query` versions declare it explicitly as being a query parameter.
/// info
Keep in mind that the most important part to make a parameter optional is the part:
```Python
= None
```
or the:
```Python
= Query(default=None)
q: str | None = None
```
as it will use that `None` as the default value, and that way make the parameter **not required**.
The `Union[str, None]` part allows your editor to provide better support, but it is not what tells FastAPI that this parameter is not required.
///
But the `Query` version declares it explicitly as being a query parameter.
Then, we can pass more parameters to `Query`. In this case, the `max_length` parameter that applies to strings:
```Python
q: Union[str, None] = Query(default=None, max_length=50)
q: str | None = Query(default=None, max_length=50)
```
This will validate the data, show a clear error when the data is not valid, and document the parameter in the OpenAPI schema *path operation*.
@ -201,7 +150,7 @@ This will validate the data, show a clear error when the data is not valid, and
Keep in mind that when using `Query` inside of `Annotated` you cannot use the `default` parameter for `Query`.
Instead use the actual default value of the function parameter. Otherwise, it would be inconsistent.
Instead, use the actual default value of the function parameter. Otherwise, it would be inconsistent.
For example, this is not allowed:
@ -255,7 +204,7 @@ This specific regular expression pattern checks that the received parameter valu
If you feel lost with all these **"regular expression"** ideas, don't worry. They are a hard topic for many people. You can still do a lot of stuff without needing regular expressions yet.
But whenever you need them and go and learn them, know that you can already use them directly in **FastAPI**.
Now you know that whenever you need them you can use them in **FastAPI**.
### Pydantic v1 `regex` instead of `pattern`
@ -296,7 +245,7 @@ q: str
instead of:
```Python
q: Union[str, None] = None
q: str | None = None
```
But we are now declaring it with `Query`, for example like:
@ -304,15 +253,7 @@ But we are now declaring it with `Query`, for example like:
//// tab | Annotated
```Python
q: Annotated[Union[str, None], Query(min_length=3)] = None
```
////
//// tab | non-Annotated
```Python
q: Union[str, None] = Query(default=None, min_length=3)
q: Annotated[str | None, Query(min_length=3)] = None
```
////
@ -321,42 +262,14 @@ So, when you need to declare a value as required while using `Query`, you can si
{* ../../docs_src/query_params_str_validations/tutorial006_an_py39.py hl[9] *}
### Required with Ellipsis (`...`)
There's an alternative way to explicitly declare that a value is required. You can set the default to the literal value `...`:
{* ../../docs_src/query_params_str_validations/tutorial006b_an_py39.py hl[9] *}
/// info
If you hadn't seen that `...` before: it is a special single value, it is <a href="https://docs.python.org/3/library/constants.html#Ellipsis" class="external-link" target="_blank">part of Python and is called "Ellipsis"</a>.
It is used by Pydantic and FastAPI to explicitly declare that a value is required.
///
This will let **FastAPI** know that this parameter is required.
### Required, can be `None`
You can declare that a parameter can accept `None`, but that it's still required. This would force clients to send a value, even if the value is `None`.
To do that, you can declare that `None` is a valid type but still use `...` as the default:
To do that, you can declare that `None` is a valid type but simply do not declare a default value:
{* ../../docs_src/query_params_str_validations/tutorial006c_an_py310.py hl[9] *}
/// tip
Pydantic, which is what powers all the data validation and serialization in FastAPI, has a special behavior when you use `Optional` or `Union[Something, None]` without a default value, you can read more about it in the Pydantic docs about <a href="https://docs.pydantic.dev/2.3/usage/models/#required-optional-fields" class="external-link" target="_blank">Required fields</a>.
///
/// tip
Remember that in most of the cases, when something is required, you can simply omit the default, so you normally don't have to use `...`.
///
## Query parameter list / multiple values
When you define a query parameter explicitly with `Query` you can also declare it to receive a list of values, or said in another way, to receive multiple values.
@ -396,7 +309,7 @@ The interactive API docs will update accordingly, to allow multiple values:
### Query parameter list / multiple values with defaults
And you can also define a default `list` of values if none are provided:
You can also define a default `list` of values if none are provided:
{* ../../docs_src/query_params_str_validations/tutorial012_an_py39.py hl[9] *}
@ -419,7 +332,7 @@ the default of `q` will be: `["foo", "bar"]` and your response will be:
#### Using just `list`
You can also use `list` directly instead of `List[str]` (or `list[str]` in Python 3.9+):
You can also use `list` directly instead of `list[str]`:
{* ../../docs_src/query_params_str_validations/tutorial013_an_py39.py hl[9] *}
@ -427,7 +340,7 @@ You can also use `list` directly instead of `List[str]` (or `list[str]` in Pytho
Keep in mind that in this case, FastAPI won't check the contents of the list.
For example, `List[int]` would check (and document) that the contents of the list are integers. But `list` alone wouldn't.
For example, `list[int]` would check (and document) that the contents of the list are integers. But `list` alone wouldn't.
///
@ -493,6 +406,68 @@ To exclude a query parameter from the generated OpenAPI schema (and thus, from t
{* ../../docs_src/query_params_str_validations/tutorial014_an_py310.py hl[10] *}
## Custom Validation
There could be cases where you need to do some **custom validation** that can't be done with the parameters shown above.
In those cases, you can use a **custom validator function** that is applied after the normal validation (e.g. after validating that the value is a `str`).
You can achieve that using <a href="https://docs.pydantic.dev/latest/concepts/validators/#field-after-validator" class="external-link" target="_blank">Pydantic's `AfterValidator`</a> inside of `Annotated`.
/// tip
Pydantic also has <a href="https://docs.pydantic.dev/latest/concepts/validators/#field-before-validator" class="external-link" target="_blank">`BeforeValidator`</a> and others. 🤓
///
For example, this custom validator checks that the item ID starts with `isbn-` for an <abbr title="ISBN means International Standard Book Number">ISBN</abbr> book number or with `imdb-` for an <abbr title="IMDB (Internet Movie Database) is a website with information about movies">IMDB</abbr> movie URL ID:
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
/// info
This is available with Pydantic version 2 or above. 😎
///
/// tip
If you need to do any type of validation that requires communicating with any **external component**, like a database or another API, you should instead use **FastAPI Dependencies**, you will learn about them later.
These custom validators are for things that can be checked with **only** the **same data** provided in the request.
///
### Understand that Code
The important point is just using **`AfterValidator` with a function inside `Annotated`**. Feel free to skip this part. 🤸
---
But if you're curious about this specific code example and you're still entertained, here are some extra details.
#### String with `value.startswith()`
Did you notice? a string using `value.startswith()` can take a tuple, and it will check each value in the tuple:
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[16:19] hl[17] *}
#### A Random Item
With `data.items()` we get an <abbr title="Something we can iterate on with a for loop, like a list, set, etc.">iterable object</abbr> with tuples containing the key and value for each dictionary item.
We convert this iterable object into a proper `list` with `list(data.items())`.
Then with `random.choice()` we can get a **random value** from the list, so, we get a tuple with `(id, name)`. It will be something like `("imdb-tt0371724", "The Hitchhiker's Guide to the Galaxy")`.
Then we **assign those two values** of the tuple to the variables `id` and `name`.
So, if the user didn't provide an item ID, they will still receive a random suggestion.
...we do all this in a **single simple line**. 🤯 Don't you love Python? 🐍
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[22:30] hl[29] *}
## Recap
You can declare additional validations and metadata for your parameters.
@ -510,6 +485,8 @@ Validations specific for strings:
* `max_length`
* `pattern`
Custom validations using `AfterValidator`.
In these examples you saw how to declare validations for `str` values.
See the next chapters to learn how to declare validations for other types, like numbers.

10
docs/en/docs/tutorial/response-status-code.md

@ -53,16 +53,16 @@ These status codes have a name associated to recognize them, but the important p
In short:
* `100` and above are for "Information". You rarely use them directly. Responses with these status codes cannot have a body.
* **`200`** and above are for "Successful" responses. These are the ones you would use the most.
* `100 - 199` are for "Information". You rarely use them directly. Responses with these status codes cannot have a body.
* **`200 - 299`** are for "Successful" responses. These are the ones you would use the most.
* `200` is the default status code, which means everything was "OK".
* Another example would be `201`, "Created". It is commonly used after creating a new record in the database.
* A special case is `204`, "No Content". This response is used when there is no content to return to the client, and so the response must not have a body.
* **`300`** and above are for "Redirection". Responses with these status codes may or may not have a body, except for `304`, "Not Modified", which must not have one.
* **`400`** and above are for "Client error" responses. These are the second type you would probably use the most.
* **`300 - 399`** are for "Redirection". Responses with these status codes may or may not have a body, except for `304`, "Not Modified", which must not have one.
* **`400 - 499`** are for "Client error" responses. These are the second type you would probably use the most.
* An example is `404`, for a "Not Found" response.
* For generic errors from the client, you can just use `400`.
* `500` and above are for server errors. You almost never use them directly. When something goes wrong at some part in your application code, or server, it will automatically return one of these status codes.
* `500 - 599` are for server errors. You almost never use them directly. When something goes wrong at some part in your application code, or server, it will automatically return one of these status codes.
/// tip

4
docs/en/docs/virtual-environments.md

@ -668,7 +668,7 @@ After activating the virtual environment, the `PATH` variable would look somethi
/home/user/code/awesome-project/.venv/bin:/usr/bin:/bin:/usr/sbin:/sbin
```
That means that the system will now start looking first look for programs in:
That means that the system will now start looking first for programs in:
```plaintext
/home/user/code/awesome-project/.venv/bin
@ -692,7 +692,7 @@ and use that one.
C:\Users\user\code\awesome-project\.venv\Scripts;C:\Windows\System32
```
That means that the system will now start looking first look for programs in:
That means that the system will now start looking first for programs in:
```plaintext
C:\Users\user\code\awesome-project\.venv\Scripts

6
docs/en/overrides/main.html

@ -88,6 +88,12 @@
<img class="sponsor-image" src="/img/sponsors/render-banner.svg" />
</a>
</div>
<div class="item">
<a title="Cut Code Review Time & Bugs in Half with CodeRabbit" style="display: block; position: relative;" href="https://www.coderabbit.ai/?utm_source=fastapi&utm_medium=banner&utm_campaign=fastapi" target="_blank">
<span class="sponsor-badge">sponsor</span>
<img class="sponsor-image" src="/img/sponsors/coderabbit-banner.png" />
</a>
</div>
</div>
</div>
{% endblock %}

2
docs/es/docs/index.md

@ -12,7 +12,7 @@
</p>
<p align="center">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">

16
docs/es/docs/tutorial/query-params-str-validations.md

@ -321,22 +321,6 @@ Así que, cuando necesites declarar un valor como requerido mientras usas `Query
{* ../../docs_src/query_params_str_validations/tutorial006_an_py39.py hl[9] *}
### Requerido con Puntos suspensivos (`...`)
Hay una manera alternativa de declarar explícitamente que un valor es requerido. Puedes establecer el valor por defecto al valor literal `...`:
{* ../../docs_src/query_params_str_validations/tutorial006b_an_py39.py hl[9] *}
/// info | Información
Si no habías visto eso `...` antes: es un valor especial único, es <a href="https://docs.python.org/3/library/constants.html#Ellipsis" class="external-link" target="_blank">parte de Python y se llama "Ellipsis"</a>.
Se usa por Pydantic y FastAPI para declarar explícitamente que un valor es requerido.
///
Esto le permitirá a **FastAPI** saber que este parámetro es requerido.
### Requerido, puede ser `None`
Puedes declarar que un parámetro puede aceptar `None`, pero que aún así es requerido. Esto obligaría a los clientes a enviar un valor, incluso si el valor es `None`.

8
docs/fa/docs/index.md

@ -11,11 +11,11 @@
<em>فریم‌ورک FastAPI، کارایی بالا، یادگیری آسان، کدنویسی سریع، آماده برای استفاده در محیط پروداکشن</em>
</p>
<p align="center">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest" target="_blank">
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg" alt="Test">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://codecov.io/gh/fastapi/fastapi" target="_blank">
<img src="https://img.shields.io/codecov/c/github/fastapi/fastapi?color=%2334D058" alt="Coverage">
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">
</a>
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Package version">

2
docs/fr/docs/index.md

@ -12,7 +12,7 @@
</p>
<p align="center">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">

6
docs/he/docs/index.md

@ -12,10 +12,10 @@
</p>
<p align="center">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://codecov.io/gh/fastapi/fastapi" target="_blank">
<img src="https://img.shields.io/codecov/c/github/fastapi/fastapi?color=%2334D058" alt="Coverage">
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">
</a>
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Package version">

2
docs/hu/docs/index.md

@ -6,7 +6,7 @@
</p>
<p align="center">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">

2
docs/id/docs/index.md

@ -12,7 +12,7 @@
</p>
<p align="center">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">

14
docs/it/docs/index.md

@ -4,15 +4,19 @@
<p align="center">
<em>FastAPI framework, alte prestazioni, facile da imparare, rapido da implementare, pronto per il rilascio in produzione</em>
</p>
<p align="center">
<a href="https://travis-ci.com/fastapi/fastapi" target="_blank">
<img src="https://travis-ci.com/fastapi/fastapi.svg?branch=master" alt="Build Status">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">
</a>
<a href="https://codecov.io/gh/fastapi/fastapi" target="_blank">
<img src="https://img.shields.io/codecov/c/github/fastapi/fastapi" alt="Coverage">
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Package version">
</a>
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://badge.fury.io/py/fastapi.svg" alt="Package version">
<img src="https://img.shields.io/pypi/pyversions/fastapi.svg?color=%2334D058" alt="Supported Python versions">
</a>
</p>

13
docs/ja/docs/index.md

@ -11,14 +11,17 @@
<em>FastAPI framework, high performance, easy to learn, fast to code, ready for production</em>
</p>
<p align="center">
<a href="https://travis-ci.com/fastapi/fastapi" target="_blank">
<img src="https://travis-ci.com/fastapi/fastapi.svg?branch=master" alt="Build Status">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://codecov.io/gh/fastapi/fastapi" target="_blank">
<img src="https://img.shields.io/codecov/c/github/fastapi/fastapi" alt="Coverage">
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">
</a>
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://badge.fury.io/py/fastapi.svg" alt="Package version">
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Package version">
</a>
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://img.shields.io/pypi/pyversions/fastapi.svg?color=%2334D058" alt="Supported Python versions">
</a>
</p>

77
docs/ja/docs/tutorial/cookie-param-models.md

@ -0,0 +1,77 @@
# クッキーパラメータモデル
もし関連する**複数のクッキー**から成るグループがあるなら、それらを宣言するために、**Pydanticモデル**を作成できます。🍪
こうすることで、**複数の場所**で**そのPydanticモデルを再利用**でき、バリデーションやメタデータを、すべてのクッキーパラメータに対して一度に宣言できます。😎
/// note | 備考
この機能は、FastAPIのバージョン `0.115.0` からサポートされています。🤓
///
/// tip | 豆知識
これと同じテクニックは `Query``Cookie``Header` にも適用できます。 😎
///
## クッキーにPydanticモデルを使用する
必要な複数の**クッキー**パラメータを**Pydanticモデル**で宣言し、さらに、それを `Cookie` として宣言しましょう:
{* ../../docs_src/cookie_param_models/tutorial001_an_py310.py hl[9:12,16] *}
**FastAPI**は、リクエストの**クッキー**から**それぞれのフィールド**のデータを**抽出**し、定義された**Pydanticモデル**を提供します。
## ドキュメントの確認
対話的APIドキュメントUI `/docs` で、定義されているクッキーを確認できます:
<div class="screenshot">
<img src="/img/tutorial/cookie-param-models/image01.png">
</div>
/// info | 備考
**ブラウザがクッキーを処理し**ていますが、特別な方法で内部的に処理を行っているために、**JavaScript**からは簡単に操作**できない**ことに留意してください。
**対話的APIドキュメントUI** `/docs` にアクセスすれば、*パスオペレーション*に関するクッキーの**ドキュメンテーション**を確認できます。
しかし、たとえ**クッキーデータを入力して**「Execute」をクリックしても、対話的APIドキュメントUIは**JavaScript**で動作しているためクッキーは送信されず、まるで値を入力しなかったかのような**エラー**メッセージが表示されます。
///
## 余分なクッキーを禁止する
特定の(あまり一般的ではないかもしれない)ケースで、受け付けるクッキーを**制限**する必要があるかもしれません。
あなたのAPIは独自の <abbr title="念のためですが、これはジョークです。クッキー同意とは関係ありませんが、APIでさえ不適切なクッキーを拒否できるとは愉快ですね。クッキーでも食べてください。🍪 (原文: This is a joke, just in case. It has nothing to do with cookie consents, but it's funny that even the API can now reject the poor cookies. Have a cookie. 🍪)">クッキー同意</abbr> を管理する能力を持っています。 🤪🍪
Pydanticのモデルの Configuration を利用して、 `extra` フィールドを `forbid` とすることができます。
{* ../../docs_src/cookie_param_models/tutorial002_an_py39.py hl[10] *}
もしクライアントが**余分なクッキー**を送ろうとすると、**エラー**レスポンスが返されます。
<abbr title="これもジョークです。気にしないでください。クッキーのお供にコーヒーでも飲んでください。☕ (原文: This is another joke. Don't pay attention to me. Have some coffee for your cookie. ☕)">どうせAPIに拒否されるのに</abbr>あなたの同意を得ようと精一杯努力する可哀想なクッキーバナーたち... 🍪
例えば、クライアントがクッキー `santa_tracker``good-list-please` という値で送ろうとすると、`santa_tracker` という <abbr title="サンタはクッキー不足を良しとはしないでしょう。🎅 はい、クッキージョークはもう止めておきます。(原文: Santa disapproves the lack of cookies. 🎅 Okay, no more cookie jokes.)">クッキーが許可されていない</abbr> ことを通知する**エラー**レスポンスが返されます:
```json
{
"detail": [
{
"type": "extra_forbidden",
"loc": ["cookie", "santa_tracker"],
"msg": "Extra inputs are not permitted",
"input": "good-list-please",
}
]
}
```
## まとめ
**FastAPI**では、<abbr title="帰ってしまう前に最後のクッキーをどうぞ。🍪 (原文: Have a last cookie before you go. 🍪)">**クッキー**</abbr>を宣言するために、**Pydanticモデル**を使用できます。😎

68
docs/ja/docs/tutorial/query-param-models.md

@ -0,0 +1,68 @@
# クエリパラメータモデル
もし関連する**複数のクエリパラメータ**から成るグループがあるなら、それらを宣言するために、**Pydanticモデル**を作成できます。
こうすることで、**複数の場所**で**そのPydanticモデルを再利用**でき、バリデーションやメタデータを、すべてのクエリパラメータに対して一度に宣言できます。😎
/// note | 備考
この機能は、FastAPIのバージョン `0.115.0` からサポートされています。🤓
///
## クエリパラメータにPydanticモデルを使用する
必要な**複数のクエリパラメータ**を**Pydanticモデル**で宣言し、さらに、それを `Query` として宣言しましょう:
{* ../../docs_src/query_param_models/tutorial001_an_py310.py hl[9:13,17] *}
**FastAPI**は、リクエストの**クエリパラメータ**からそれぞれの**フィールド**のデータを**抽出**し、定義された**Pydanticモデル**を提供します。
## ドキュメントの確認
対話的APIドキュメント `/docs` でクエリパラメータを確認できます:
<div class="screenshot">
<img src="/img/tutorial/query-param-models/image01.png">
</div>
## 余分なクエリパラメータを禁止する
特定の(あまり一般的ではないかもしれない)ケースで、受け付けるクエリパラメータを**制限**する必要があるかもしれません。
Pydanticのモデルの Configuration を利用して、 `extra` フィールドを `forbid` とすることができます。
{* ../../docs_src/query_param_models/tutorial002_an_py310.py hl[10] *}
もしクライアントが**クエリパラメータ**として**余分な**データを送ろうとすると、**エラー**レスポンスが返されます。
例えば、クライアントがクエリパラメータ `tool` に、値 `plumbus` を設定して送ろうとすると:
```http
https://example.com/items/?limit=10&tool=plumbus
```
クエリパラメータ `tool` が許可されていないことを通知する**エラー**レスポンスが返されます。
```json
{
"detail": [
{
"type": "extra_forbidden",
"loc": ["query", "tool"],
"msg": "Extra inputs are not permitted",
"input": "plumbus"
}
]
}
```
## まとめ
**FastAPI**では、**クエリパラメータ**を宣言するために、**Pydanticモデル**を使用できます。😎
/// tip | 豆知識
ネタバレ注意: Pydanticモデルはクッキーやヘッダーの宣言にも使用できますが、その内容については後のチュートリアルで学びます。🤫
///

313
docs/ko/docs/advanced/custom-response.md

@ -0,0 +1,313 @@
# 사용자 정의 응답 - HTML, Stream, 파일, 기타
기본적으로, **FastAPI** 응답을 `JSONResponse`를 사용하여 반환합니다.
이를 재정의 하려면 [응답을 직접 반환하기](response-directly.md){.internal-link target=_blank}에서 본 것처럼 `Response`를 직접 반환하면 됩니다.
그러나 `Response` (또는 `JSONResponse`와 같은 하위 클래스)를 직접 반환하면, 데이터가 자동으로 변환되지 않으며 (심지어 `response_model`을 선언했더라도), 문서화가 자동으로 생성되지 않습니다(예를 들어, 생성된 OpenAPI의 일부로 HTTP 헤더 `Content-Type`에 특정 "미디어 타입"을 포함하는 경우).
하지만 *경로 작업 데코레이터*에서 `response_class` 매개변수를 사용하여 원하는 `Response`(예: 모든 `Response` 하위 클래스)를 선언할 수도 있습니다.
*경로 작업 함수*에서 반환하는 내용은 해당 `Response`안에 포함됩니다.
그리고 만약 그 `Response``JSONResponse``UJSONResponse`의 경우 처럼 JSON 미디어 타입(`application/json`)을 가지고 있다면, *경로 작업 데코레이터*에서 선언한 Pydantic의 `response_model`을 사용해 자동으로 변환(및 필터링) 됩니다.
/// note | 참고
미디어 타입이 없는 응답 클래스를 사용하는 경우, FastAPI는 응답에 내용이 없을 것으로 예상하므로 생성된 OpenAPI 문서에서 응답 형식을 문서화하지 않습니다.
///
## `ORJSONResponse` 사용하기
예를 들어, 성능을 극대화하려는 경우, <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">orjson</a>을 설치하여 사용하고 응답을 `ORJSONResponse`로 설정할 수 있습니다.
사용하고자 하는 `Response` 클래스(하위 클래스)를 임포트한 후, **경로 작업 데코레이터*에서 선언하세요.
대규모 응답의 경우, 딕셔너리를 반환하는 것보다 `Response`를 반환하는 것이 훨씬 빠릅니다.
이유는 기본적으로, FastAPI가 내부의 모든 항목을 검사하고 JSON으로 직렬화할 수 있는지 확인하기 때문입니다. 이는 사용자 안내서에서 설명된 [JSON 호환 가능 인코더](../tutorial/encoder.md){.internal-link target=_blank}를 사용하는 방식과 동일합니다. 이를 통해 데이터베이스 모델과 같은 **임의의 객체**를 반환할 수 있습니다.
하지만 반환하는 내용이 **JSON으로 직렬화 가능**하다고 확신하는 경우, 해당 내용을 응답 클래스에 직접 전달할 수 있으며, FastAPI가 반환 내용을 `jsonable_encoder`를 통해 처리한 뒤 응답 클래스에 전달하는 오버헤드를 피할 수 있습니다.
{* ../../docs_src/custom_response/tutorial001b.py hl[2,7] *}
/// info | 정보
`response_class` 매개변수는 응답의 "미디어 타입"을 정의하는 데에도 사용됩니다.
이 경우, HTTP 헤더 `Content-Type``application/json`으로 설정됩니다.
그리고 이는 OpenAPI에 그대로 문서화됩니다.
///
/// tip | 팁
`ORJSONResponse`는 FastAPI에서만 사용할 수 있고 Starlette에서는 사용할 수 없습니다.
///
## HTML 응답
**FastAPI**에서 HTML 응답을 직접 반환하려면 `HTMLResponse`를 사용하세요.
* `HTMLResponse`를 임포트 합니다.
* *경로 작업 데코레이터*의 `response_class` 매개변수로 `HTMLResponse`를 전달합니다.
{* ../../docs_src/custom_response/tutorial002.py hl[2,7] *}
/// info | 정보
`response_class` 매개변수는 응답의 "미디어 타입"을 정의하는 데에도 사용됩니다.
이 경우, HTTP 헤더 `Content-Type``text/html`로 설정됩니다.
그리고 이는 OpenAPI에 그대로 문서화 됩니다.
///
### `Response` 반환하기
[응답을 직접 반환하기](response-directly.md){.internal-link target=_blank}에서 본 것 처럼, *경로 작업*에서 응답을 직접 반환하여 재정의할 수도 있습니다.
위의 예제와 동일하게 `HTMLResponse`를 반환하는 코드는 다음과 같을 수 있습니다:
{* ../../docs_src/custom_response/tutorial003.py hl[2,7,19] *}
/// warning | 경고
*경로 작업 함수*에서 직접 반환된 `Response`는 OpenAPI에 문서화되지 않습니다(예를들어, `Content-Type`이 문서화되지 않음) 자동 대화형 문서에서도 표시되지 않습니다.
///
/// info | 정보
물론 실제 `Content-Type` 헤더, 상태 코드 등은 반환된 `Response` 객체에서 가져옵니다.
///
### OpenAPI에 문서화하고 `Response` 재정의 하기
함수 내부에서 응답을 재정의하면서 동시에 OpenAPI에서 "미디어 타입"을 문서화하고 싶다면, `response_class` 매게변수를 사용하면서 `Response` 객체를 반환할 수 있습니다.
이 경우 `response_class`는 OpenAPI *경로 작업*을 문서화하는 데만 사용되고, 실제로는 여러분이 반환한 `Response`가 그대로 사용됩니다.
### `HTMLResponse`직접 반환하기
예를 들어, 다음과 같이 작성할 수 있습니다:
{* ../../docs_src/custom_response/tutorial004.py hl[7,21,23] *}
이 예제에서, `generate_html_response()` 함수는 HTML을 `str`로 반환하는 대신 이미 `Response`를 생성하고 반환합니다.
`generate_html_response()`를 호출한 결과를 반환함으로써, 기본적인 **FastAPI** 기본 동작을 재정의 하는 `Response`를 이미 반환하고 있습니다.
하지만 `response_class``HTMLResponse`를 함께 전달했기 때문에, FastAPI는 이를 OpenAPI 및 대화형 문서에서 `text/html`로 HTML을 문서화 하는 방법을 알 수 있습니다.
<img src="/img/tutorial/custom-response/image01.png">
## 사용 가능한 응답들
다음은 사용할 수 있는 몇가지 응답들 입니다.
`Response`를 사용하여 다른 어떤 것도 반환 할수 있으며, 직접 하위 클래스를 만들 수도 있습니다.
/// note | 기술 세부사항
`from starlette.responses import HTMLResponse`를 사용할 수도 있습니다.
**FastAPI**는 개발자인 여러분의 편의를 위해 `starlette.responses``fastapi.responses`로 제공 하지만, 대부분의 사용 가능한 응답은 Starlette에서 직접 가져옵니다.
///
### `Response`
기본 `Response` 클래스는 다른 모든 응답 클래스의 부모 클래스 입니다.
이 클래스를 직접 반환할 수 있습니다.
다음 매개변수를 받을 수 있습니다:
* `content` - `str` 또는 `bytes`.
* `status_code` - HTTP 상태코드를 나타내는 `int`.
* `headers` - 문자열로 이루어진 `dict`.
* `media_type` - 미디어 타입을 나타내는 `str` 예: `"text/html"`.
FastAPI (실제로는 Starlette)가 자동으로 `Content-Length` 헤더를 포함시킵니다. 또한 `media_type`에 기반하여 `Content-Type` 헤더를 포함하며, 텍스트 타입의 경우 문자 집합을 추가 합니다.
{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
### `HTMLResponse`
텍스트 또는 바이트를 받아 HTML 응답을 반환합니다. 위에서 설명한 내용과 같습니다.
### `PlainTextResponse`
텍스트 또는 바이트를 받아 일반 텍스트 응답을 반환합니다.
{* ../../docs_src/custom_response/tutorial005.py hl[2,7,9] *}
### `JSONResponse`
데이터를 받아 `application/json`으로 인코딩된 응답을 반환합니다.
이는 위에서 설명했듯이 **FastAPI**에서 기본적으로 사용되는 응답 형식입니다.
### `ORJSONResponse`
<a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>을 사용하여 빠른 JSON 응답을 제공하는 대안입니다. 위에서 설명한 내용과 같습니다.
/// info | 정보
이를 사용하려면 `orjson`을 설치해야합니다. 예: `pip install orjson`.
///
### `UJSONResponse`
<a href="https://github.com/ultrajson/ultrajson" class="external-link" target="_blank">`ujson`</a>을 사용한 또 다른 JSON 응답 형식입니다.
/// info | 정보
이 응답을 사용하려면 `ujson`을 설치해야합니다. 예: 'pip install ujson`.
///
/// warning | 경고
`ujson` 은 일부 예외 경우를 처리하는 데 있어 Python 내장 구현보다 덜 엄격합니다.
///
{* ../../docs_src/custom_response/tutorial001.py hl[2,7] *}
/// tip | 팁
`ORJSONResponse`가 더 빠른 대안일 가능성이 있습니다.
///
### `RedirectResponse`
HTTP 리디렉션 응답을 반환합니다. 기본적으로 상태 코드는 307(임시 리디렉션)으로 설정됩니다.
`RedirectResponse`를 직접 반환할 수 있습니다.
{* ../../docs_src/custom_response/tutorial006.py hl[2,9] *}
---
또는 `response_class` 매개변수에서 사용할 수도 있습니다:
{* ../../docs_src/custom_response/tutorial006b.py hl[2,7,9] *}
이 경우, *경로 작업* 함수에서 URL을 직접 반환할 수 있습니다.
이 경우, 사용되는 `status_code``RedirectResponse`의 기본값인 `307` 입니다.
---
`status_code` 매개변수를 `response_class` 매개변수와 함께 사용할 수도 있습니다:
{* ../../docs_src/custom_response/tutorial006c.py hl[2,7,9] *}
### `StreamingResponse`
비동기 제너레이터 또는 일반 제너레이터/이터레이터를 받아 응답 본문을 스트리밍 합니다.
{* ../../docs_src/custom_response/tutorial007.py hl[2,14] *}
#### 파일과 같은 객체를 사용한 `StreamingResponse`
파일과 같은 객체(예: `open()`으로 반환된 객체)가 있는 경우, 해당 파일과 같은 객체를 반복(iterate)하는 제너레이터 함수를 만들 수 있습니다.
이 방식으로, 파일 전체를 메모리에 먼저 읽어들일 필요 없이, 제너레이터 함수를 `StreamingResponse`에 전달하여 반환할 수 있습니다.
이 방식은 클라우드 스토리지, 비디오 처리 등의 다양한 라이브러리와 함께 사용할 수 있습니다.
{* ../../docs_src/custom_response/tutorial008.py hl[2,10:12,14] *}
1. 이것이 제너레이터 함수입니다. `yield` 문을 포함하고 있으므로 "제너레이터 함수"입니다.
2. `with` 블록을 사용함으로써, 제너레이터 함수가 완료된 후 파일과 같은 객체가 닫히도록 합니다. 즉, 응답 전송이 끝난 후 닫힙니다.
3. 이 `yield from`은 함수가 `file_like`라는 객체를 반복(iterate)하도록 합니다. 반복된 각 부분은 이 제너레이터 함수(`iterfile`)에서 생성된 것처럼 `yield` 됩니다.
이렇게 하면 "생성(generating)" 작업을 내부적으로 다른 무언가에 위임하는 제너레이터 함수가 됩니다.
이 방식을 사용하면 `with` 블록 안에서 파일을 열 수 있어, 작업이 완료된 후 파일과 같은 객체가 닫히는 것을 보장할 수 있습니다.
/// tip | 팁
여기서 표준 `open()`을 사용하고 있기 때문에 `async``await`를 지원하지 않습니다. 따라서 경로 작업은 일반 `def`로 선언합니다.
///
### `FileResponse`
파일을 비동기로 스트리밍하여 응답합니다.
다른 응답 유형과는 다른 인수를 사용하여 객체를 생성합니다:
* `path` - 스트리밍할 파일의 경로.
* `headers` - 딕셔너리 형식의 사용자 정의 헤더.
* `media_type` - 미디어 타입을 나타내는 문자열. 설정되지 않은 경우 파일 이름이나 경로를 사용하여 추론합니다.
* `filename` - 설정된 경우 응답의 `Content-Disposition`에 포함됩니다.
파일 응답에는 적절한 `Content-Length`, `Last-Modified`, 및 `ETag` 헤더가 포함됩니다.
{* ../../docs_src/custom_response/tutorial009.py hl[2,10] *}
또한 `response_class` 매개변수를 사용할 수도 있습니다:
{* ../../docs_src/custom_response/tutorial009b.py hl[2,8,10] *}
이 경우, 경로 작업 함수에서 파일 경로를 직접 반환할 수 있습니다.
## 사용자 정의 응답 클래스
`Response`를 상속받아 사용자 정의 응답 클래스를 생성하고 사용할 수 있습니다.
예를 들어, 포함된 `ORJSONResponse` 클래스에서 사용되지 않는 설정으로 <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">orjson</a>을 사용하고 싶다고 가정해봅시다.
만약 들여쓰기 및 포맷된 JSON을 반환하고 싶다면, `orjson.OPT_INDENT_2` 옵션을 사용할 수 있습니다.
`CustomORJSONResponse`를 생성할 수 있습니다. 여기서 핵심은 `Response.render(content)` 메서드를 생성하여 내용을 `bytes`로 반환하는 것입니다:
{* ../../docs_src/custom_response/tutorial009c.py hl[9:14,17] *}
이제 다음 대신:
```json
{"message": "Hello World"}
```
이 응답은 이렇게 반환됩니다:
```json
{
"message": "Hello World"
}
```
물론 JSON 포맷팅보다 더 유용하게 활용할 방법을 찾을 수 있을 것입니다. 😉
## 기본 응답 클래스
**FastAPI** 클래스 객체 또는 `APIRouter`를 생성할 때 기본적으로 사용할 응답 클래스를 지정할 수 있습니다.
이를 정의하는 매개변수는 `default_response_class`입니다.
아래 예제에서 **FastAPI**는 모든 경로 작업에서 기본적으로 `JSONResponse` 대신 `ORJSONResponse`를 사용합니다.
{* ../../docs_src/custom_response/tutorial010.py hl[2,4] *}
/// tip | 팁
여전히 이전처럼 *경로 작업*에서 `response_class`를 재정의할 수 있습니다.
///
## 추가 문서화
OpenAPI에서 `responses`를 사용하여 미디어 타입 및 기타 세부 정보를 선언할 수도 있습니다: [OpenAPI에서 추가 응답](additional-responses.md){.internal-link target=_blank}.

287
docs/ko/docs/help-fastapi.md

@ -1,162 +1,269 @@
* # FastAPI 지원 - 도움 받기
# FastAPI 지원 - 도움 받기
**FastAPI** 가 마음에 드시나요?
**FastAPI** 가 마음에 드시나요?
FastAPI, 다른 사용자, 개발자를 응원하고 싶으신가요?
FastAPI, 다른 사용자, 개발자를 응원하고 싶으신가요?
혹은 **FastAPI** 에 대해 도움이 필요하신가요?
혹은 **FastAPI** 에 대해 도움이 필요하신가요?
아주 간단하게 응원할 수 있습니다 (몇 번의 클릭만으로).
아주 간단하게 응원할 수 있습니다 (몇 번의 클릭만으로).
또한 도움을 받을 수 있는 방법도 몇 가지 있습니다.
또한 도움을 받을 수 있는 방법도 몇 가지 있습니다.
## 뉴스레터 구독
## 뉴스레터 구독
[**FastAPI와 친구** 뉴스레터](https://github.com/fastapi/fastapi/blob/master/newsletter)를 구독하여 최신 정보를 유지할 수 있습니다{.internal-link target=_blank}:
[**FastAPI and friends** 뉴스레터](newsletter.md){.internal-link target=\_blank}를 구독하여 최신 정보를 유지할 수 있습니다:
- FastAPI 와 그 친구들에 대한 뉴스 🚀
- 가이드 📝
- 특징
- 획기적인 변화 🚨
- 팁과 요령 ✅
* FastAPI and friends에 대한 뉴스 🚀
* 가이드 📝
* 기능
* 획기적인 변화 🚨
* 팁과 요령 ✅
## 트위터에서 FastAPI 팔로우하기
## 트위터에서 FastAPI 팔로우하기
[Follow @fastapi on **Twitter**](https://twitter.com/fastapi) 를 팔로우하여 **FastAPI** 에 대한 최신 뉴스를 얻을 수 있습니다. 🐦
<a href="https://twitter.com/fastapi" class="external-link" target="_blank">**Twitter**의 @fastapi를 팔로우</a>하여 **FastAPI** 에 대한 최신 뉴스를 얻을 수 있습니다. 🐦
## Star **FastAPI** in GitHub
## Star **FastAPI** in GitHub
GitHub에서 FastAPI에 "star"를 붙일 수 있습니다(오른쪽 상단의 star 버튼을 클릭): https://github.com/fastapi/fastapi. ⭐️
GitHub에서 FastAPI에 "star"를 붙일 수 있습니다 (오른쪽 상단의 star 버튼을 클릭): <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>. ⭐️
스타를 늘림으로써, 다른 사용자들이 좀 더 쉽게 찾을 수 있고, 많은 사람들에게 유용한 것임을 나타낼 수 있습니다.
스타를 늘림으로써, 다른 사용자들이 좀 더 쉽게 찾을 수 있고, 많은 사람들에게 유용한 것임을 나타낼 수 있습니다.
## GitHub 저장소에서 릴리즈 확인
## GitHub 저장소에서 릴리즈 확인
GitHub에서 FastAPI를 "watch"할 수 있습니다 (오른쪽 상단 watch 버튼을 클릭): https://github.com/fastapi/fastapi. 👀
GitHub에서 FastAPI를 "watch"할 수 있습니다 (오른쪽 상단 watch 버튼을 클릭): <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>. 👀
여기서 "Releases only"을 선택할 수 있습니다.
여기서 "Releases only"을 선택할 수 있습니다.
이렇게하면, **FastAPI** 의 버그 수정 및 새로운 기능의 구현 등의 새로운 자료 (최신 버전)이 있을 때마다 (이메일) 통지를 받을 수 있습니다.
이렇게하면, **FastAPI** 의 버그 수정 및 새로운 기능의 구현 등의 새로운 자료 (최신 버전)이 있을 때마다 (이메일) 통지를 받을 수 있습니다.
## 개발자와의 연결
## 개발자와의 연결
개발자인 [me (Sebastián Ramírez / `tiangolo`)](https://tiangolo.com/) 와 연락을 취할 수 있습니다.
<a href="https://tiangolo.com" class="external-link" target="_blank">개발자(Sebastián Ramírez / `tiangolo`)</a>와 연락을 취할 수 있습니다.
여러분은 할 수 있습니다:
여러분은 할 수 있습니다:
- [**GitHub**에서 팔로우하기](https://github.com/tiangolo).
- 당신에게 도움이 될 저의 다른 오픈소스 프로젝트를 확인하십시오.
- 새로운 오픈소스 프로젝트를 만들었을 때 확인하려면 팔로우 하십시오.
* <a href="https://github.com/tiangolo" class="external-link" target="_blank">**GitHub**에서 팔로우하기.</a>.
* 당신에게 도움이 될 저의 다른 오픈소스 프로젝트를 확인하십시오.
* 새로운 오픈소스 프로젝트를 만들었을 때 확인하려면 팔로우 하십시오.
* <a href="https://twitter.com/tiangolo" class="external-link" target="_blank">**Twitter**</a> 또는 <a href="https://fosstodon.org/@tiangolo" class="external-link" target="_blank">Mastodon</a>에서 팔로우하기.
* FastAPI의 사용 용도를 알려주세요 (그것을 듣는 것을 좋아합니다).
* 발표나 새로운 툴 출시 소식을 받아보십시오.
* <a href="https://twitter.com/fastapi" class="external-link" target="_blank">**Twitter**의 @fastapi를 팔로우</a> (별도 계정에서) 할 수 있습니다.
* <a href="https://www.linkedin.com/in/tiangolo/" class="external-link" target="_blank">**LinkedIn**에서 팔로우하기.</a>.
* 새로운 툴의 발표나 출시 소식을 받아보십시오. (단, Twitter를 더 자주 사용합니다 🤷‍♂).
* <a href="https://dev.to/tiangolo" class="external-link" target="_blank">**Dev.to**</a> 또는 <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">**Medium**</a>에서 제가 작성한 내용을 읽어 보십시오 (또는 팔로우).
* 다른 기사나 아이디어들을 읽고, 제가 만들어왔던 툴에 대해서도 읽으십시오.
* 새로운 기사를 읽기 위해 팔로우 하십시오.
- [**Twitter**에서 팔로우하기](https://twitter.com/tiangolo).
- FastAPI의 사용 용도를 알려주세요 (그것을 듣는 것을 좋아합니다).
- 발표 또는 새로운 툴 출시할 때 들으십시오.
- [follow @fastapi on Twitter](https://twitter.com/fastapi) (별도 계정에서) 할 수 있습니다.
## **FastAPI**에 대한 트윗
- [**Linkedin**에서의 연결](https://www.linkedin.com/in/tiangolo/).
- 새로운 툴의 발표나 릴리스를 들을 수 있습니다 (단, Twitter를 더 자주 사용합니다 🤷‍♂).
<a href="https://twitter.com/compose/tweet?text=I'm loving @fastapi because... https://github.com/fastapi/fastapi" class="external-link" target="_blank">**FastAPI**에 대해 트윗</a> 하고 FastAPI가 마음에 드는 이유를 알려주세요. 🎉
- [**Dev.to**](https://dev.to/tiangolo) 또는 [**Medium**](https://medium.com/@tiangolo)에서 제가 작성한 내용을 읽어 보십시오(또는 팔로우).
- 다른 기사나 아이디어들을 읽고, 제가 만들어왔던 툴에 대해서도 읽으십시오.
- 새로운 기사를 읽기 위해 팔로우 하십시오.
**FastAPI**가 어떻게 사용되고 있는지, 어떤 점이 마음에 들었는지, 어떤 프로젝트/회사에서 사용하고 있는지 등에 대해 듣고 싶습니다.
## **FastAPI**에 대한 트윗
## FastAPI에 투표하기
[**FastAPI**에 대해 트윗](https://twitter.com/compose/tweet?text=I'm loving @fastapi because... https://github.com/fastapi/fastapi) 하고 FastAPI가 마음에 드는 이유를 알려주세요. 🎉
* <a href="https://www.slant.co/options/34241/~fastapi-review" class="external-link" target="_blank">Slant에서 **FastAPI** 에 대해 투표하십시오</a>.
* <a href="https://alternativeto.net/software/fastapi/about/" class="external-link" target="_blank">AlternativeTo에서 **FastAPI** 에 대해 투표하십시오</a>.
* <a href="https://stackshare.io/pypi-fastapi" class="external-link" target="_blank">StackShare에서 **FastAPI** 에 대해 투표하십시오</a>.
**FastAPI**가 어떻게 사용되고 있는지, 어떤 점이 마음에 들었는지, 어떤 프로젝트/회사에서 사용하고 있는지 등에 대해 듣고 싶습니다.
## GitHub의 이슈로 다른사람 돕기
## FastAPI에 투표하기
다른 사람들의 질문에 도움을 줄 수 있습니다:
- [Slant에서 **FastAPI** 에 대해 투표하십시오](https://www.slant.co/options/34241/~fastapi-review).
- [AlternativeTo**FastAPI** 에 대해 투표하십시오](https://alternativeto.net/software/fastapi/).
* <a href="https://github.com/fastapi/fastapi/discussions/categories/questions?discussions_q=category%3AQuestions+is%3Aunanswered" class="external-link" target="_blank">GitHub 디스커션</a>
* <a href="https://github.com/fastapi/fastapi/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Aquestion+-label%3Aanswered+" class="external-link" target="_blank">GitHub 이슈</a>
## GitHub의 이슈로 다른사람 돕기
많은 경우, 여러분은 이미 그 질문에 대한 답을 알고 있을 수도 있습니다. 🤓
[존재하는 이슈](https://github.com/fastapi/fastapi/issues)를 확인하고 그것을 시도하고 도와줄 수 있습니다. 대부분의 경우 이미 답을 알고 있는 질문입니다. 🤓
만약 많은 사람들의 문제를 도와준다면, 공식적인 [FastAPI 전문가](fastapi-people.md#fastapi-experts){.internal-link target=\_blank} 가 될 것입니다. 🎉
많은 사람들의 문제를 도와준다면, 공식적인 [FastAPI 전문가](https://github.com/fastapi/fastapi/blob/master/docs/en/docs/fastapi-people.md#experts) 가 될 수 있습니다{.internal-link target=_blank}. 🎉
가장 중요한 점은: 친절하려고 노력하는 것입니다. 사람들은 좌절감을 안고 오며, 많은 경우 최선의 방식으로 질문하지 않을 수도 있습니다. 하지만 최대한 친절하게 대하려고 노력하세요. 🤗
## GitHub 저장소 보기
**FastAPI** 커뮤니티의 목표는 친절하고 환영하는 것입니다. 동시에, 괴롭힘이나 무례한 행동을 받아들이지 마세요. 우리는 서로를 돌봐야 합니다.
GitHub에서 FastAPI를 "watch"할 수 있습니다 (오른쪽 상단 watch 버튼을 클릭): https://github.com/fastapi/fastapi. 👀
---
"Releases only" 대신 "Watching"을 선택하면 다른 사용자가 새로운 issue를 생성할 때 알림이 수신됩니다.
다른 사람들의 질문 (디스커션 또는 이슈에서) 해결을 도울 수 있는 방법은 다음과 같습니다.
그런 다음 이런 issues를 해결 할 수 있도록 도움을 줄 수 있습니다.
### 질문 이해하기
## 이슈 생성하기
* 질문하는 사람이 가진 **목적**과 사용 사례를 이해할 수 있는지 확인하세요.
GitHub 저장소에 [새로운 이슈 생성](https://github.com/fastapi/fastapi/issues/new/choose) 을 할 수 있습니다, 예를들면 다음과 같습니다:
* 질문 (대부분은 질문입니다)이 **명확**한지 확인하세요.
- **질문**을 하거나 **문제**에 대해 질문합니다.
- 새로운 **기능**을 제안 합니다.
* 많은 경우, 사용자가 가정한 해결책에 대한 질문을 하지만, 더 **좋은** 해결책이 있을 수 있습니다. 문제와 사용 사례를 더 잘 이해하면 더 나은 **대안적인 해결책**을 제안할 수 있습니다.
**참고**: 만약 이슈를 생성한다면, 저는 여러분에게 다른 사람들을 도와달라고 부탁할 것입니다. 😉
* 질문을 이해할 수 없다면, 더 **자세한 정보**를 요청하세요.
## Pull Request를 만드십시오
### 문제 재현하기
Pull Requests를 이용하여 소스코드에 [컨트리뷰트](https://github.com/fastapi/fastapi/blob/master/docs/en/docs/contributing.md){.internal-link target=_blank} 할 수 있습니다. 예를 들면 다음과 같습니다:
대부분의 경우, 질문은 질문자의 **원본 코드**와 관련이 있습니다.
- 문서에서 찾은 오타를 수정할 때.
많은 경우, 코드의 일부만 복사해서 올리지만, 그것만으로는 **문제를 재현**하기에 충분하지 않습니다.
- FastAPI를 [편집하여](https://github.com/fastapi/fastapi/edit/master/docs/en/data/external_links.yml) 작성했거나 찾은 문서, 비디오 또는 팟캐스트를 공유할 때.
* 질문자에게 <a href="https://stackoverflow.com/help/minimal-reproducible-example" class="external-link" target="_blank">최소한의 재현 가능한 예제</a>를 제공해달라고 요청하세요. 이렇게 하면 코드를 **복사-붙여넣기**하여 직접 실행하고, 동일한 오류나 동작을 확인하거나 사용 사례를 더 잘 이해할 수 있습니다.
- 해당 섹션의 시작 부분에 링크를 추가했는지 확인하십시오.
* 너그러운 마음이 든다면, 문제 설명만을 기반으로 직접 **예제를 만들어**볼 수도 있습니다. 하지만, 이는 시간이 많이 걸릴 수 있으므로, 먼저 질문을 명확히 해달라고 요청하는 것이 좋습니다.
- 당신의 언어로 [문서 번역하는데](https://github.com/fastapi/fastapi/blob/master/docs/en/docs/contributing.md#translations){.internal-link target=_blank} 기여할 때.
### 해결책 제안하기
- 또한 다른 사용자가 만든 번역을 검토하는데 도움을 줄 수도 있습니다.
* 질문을 충분히 이해한 후에는 가능한 **답변**을 제공할 수 있습니다.
- 새로운 문서의 섹션을 제안할 때.
* 많은 경우, 질문자의 **근본적인 문제나 사용 사례**를 이해하는 것이 중요합니다. 그들이 시도하는 방법보다 더 나은 해결책이 있을 수 있기 때문입니다.
- 기존 문제/버그를 수정할 때.
### 해결 요청하기
- 새로운 feature를 추가할 때.
질문자가 답변을 확인하고 나면, 당신이 문제를 해결했을 가능성이 높습니다. 축하합니다, **당신은 영웅입니다**! 🦸
## 채팅에 참여하십시오
* 이제 문제를 해결했다면, 질문자에게 다음을 요청할 수 있습니다.
👥 [디스코드 채팅 서버](https://discord.gg/VQjSZaeJmf) 👥 에 가입하고 FastAPI 커뮤니티에서 다른 사람들과 어울리세요.
* GitHub 디스커션에서: 댓글을 **답변**으로 표시하도록 요청하세요.
* GitHub 이슈에서: 이슈를 **닫아달라고** 요청하세요.
/// tip
## GitHub 저장소 보기
질문이 있는 경우, [GitHub 이슈 ](https://github.com/fastapi/fastapi/issues/new/choose) 에서 질문하십시오, [FastAPI 전문가](https://github.com/fastapi/fastapi/blob/master/docs/en/docs/fastapi-people.md#experts) 의 도움을 받을 가능성이 높습니다{.internal-link target=_blank} .
GitHub에서 FastAPI를 "watch"할 수 있습니다 (오른쪽 상단 watch 버튼을 클릭): <a href="https://github.com/fastapi/fastapi" class="external-link" target="_blank">https://github.com/fastapi/fastapi</a>. 👀
///
"Releases only" 대신 "Watching"을 선택하면, 새로운 이슈나 질문이 생성될 때 알림을 받을 수 있습니다. 또한, 특정하게 새로운 이슈, 디스커션, PR 등만 알림 받도록 설정할 수도 있습니다.
```
다른 일반적인 대화에서만 채팅을 사용하십시오.
```
그런 다음 이런 이슈들을 해결 할 수 있도록 도움을 줄 수 있습니다.
기존 [지터 채팅](https://gitter.im/fastapi/fastapi) 이 있지만 채널과 고급기능이 없어서 대화를 하기가 조금 어렵기 때문에 지금은 디스코드가 권장되는 시스템입니다.
## 이슈 생성하기
### 질문을 위해 채팅을 사용하지 마십시오
GitHub 저장소에 <a href="https://github.com/fastapi/fastapi/discussions/new?category=questions" class="external-link" target="_blank">새로운 이슈 생성</a>을 할 수 있습니다, 예를들면 다음과 같습니다:
채팅은 더 많은 "자유로운 대화"를 허용하기 때문에, 너무 일반적인 질문이나 대답하기 어려운 질문을 쉽게 질문을 할 수 있으므로, 답변을 받지 못할 수 있습니다.
* **질문**을 하거나 **문제**에 대해 질문합니다.
* 새로운 **기능**을 제안 합니다.
GitHub 이슈에서의 템플릿은 올바른 질문을 작성하도록 안내하여 더 쉽게 좋은 답변을 얻거나 질문하기 전에 스스로 문제를 해결할 수도 있습니다. 그리고 GitHub에서는 시간이 조금 걸리더라도 항상 모든 것에 답할 수 있습니다. 채팅 시스템에서는 개인적으로 그렇게 할 수 없습니다. 😅
**참고**: 만약 이슈를 생성한다면, 저는 여러분에게 다른 사람들을 도와달라고 부탁할 것입니다. 😉
채팅 시스템에서의 대화 또한 GitHub에서 처럼 쉽게 검색할 수 없기 때문에 대화 중에 질문과 답변이 손실될 수 있습니다. 그리고 GitHub 이슈에 있는 것만 [FastAPI 전문가](https://github.com/fastapi/fastapi/blob/master/docs/en/docs/fastapi-people.md#experts)가 되는 것으로 간주되므로{.internal-link target=_blank} , GitHub 이슈에서 더 많은 관심을 받을 것입니다.
## Pull Requests 리뷰하기
반면, 채팅 시스템에는 수천 명의 사용자가 있기 때문에, 거의 항상 대화 상대를 찾을 가능성이 높습니다. 😄
다른 사람들의 pull request를 리뷰하는 데 도움을 줄 수 있습니다.
## 개발자 스폰서가 되십시오
다시 한번 말하지만, 최대한 친절하게 리뷰해 주세요. 🤗
[GitHub 스폰서](https://github.com/sponsors/tiangolo) 를 통해 개발자를 경제적으로 지원할 수 있습니다.
---
감사하다는 말로 커피를 ☕️ 한잔 사줄 수 있습니다. 😄
Pull Rrquest를 리뷰할 때 고려해야 할 사항과 방법은 다음과 같습니다:
또한 FastAPI의 실버 또는 골드 스폰서가 될 수 있습니다. 🏅🎉
### 문제 이해하기
## FastAPI를 강화하는 도구의 스폰서가 되십시오
* 먼저, 해당 pull request가 해결하려는 **문제를 이해하는지** 확인하세요. GitHub 디스커션 또는 이슈에서 더 긴 논의가 있었을 수도 있습니다.
문서에서 보았듯이, FastAPI는 Starlette과 Pydantic 라는 거인의 어깨에 타고 있습니다.
* Pull request가 필요하지 않을 가능성도 있습니다. **다른 방식**으로 문제를 해결할 수 있다면, 그 방법을 제안하거나 질문할 수 있습니다.
다음의 스폰서가 될 수 있습니다
### 스타일에 너무 신경 쓰지 않기
- [Samuel Colvin (Pydantic)](https://github.com/sponsors/samuelcolvin)
- [Encode (Starlette, Uvicorn)](https://github.com/sponsors/encode)
* 커밋 메시지 스타일 같은 것에 너무 신경 쓰지 않아도 됩니다. 저는 직접 커밋을 수정하여 squash and merge를 수행할 것입니다.
------
* 코드 스타일 규칙도 걱정할 필요 없습니다. 이미 자동화된 도구들이 이를 검사하고 있습니다.
감사합니다! 🚀
스타일이나 일관성 관련 요청이 필요한 경우, 제가 직접 요청하거나 필요한 변경 사항을 추가 커밋으로 수정할 것입니다.
### 코드 확인하기
* 코드를 읽고, **논리적으로 타당**한지 확인한 후 로컬에서 실행하여 문제가 해결되는지 확인하세요.
* 그런 다음, 확인했다고 **댓글**을 남겨 주세요. 그래야 제가 검토했음을 알 수 있습니다.
/// info
불행히도, 제가 단순히 여러 개의 승인만으로 PR을 신뢰할 수는 없습니다.
3개, 5개 이상의 승인이 달린 PR이 실제로는 깨져 있거나, 버그가 있거나, 주장하는 문제를 해결하지 못하는 경우가 여러 번 있었습니다. 😅
따라서, 정말로 코드를 읽고 실행한 뒤, 댓글로 확인 내용을 남겨 주는 것이 매우 중요합니다. 🤓
///
* PR을 더 단순하게 만들 수 있다면 그렇게 요청할 수 있지만, 너무 까다로울 필요는 없습니다. 주관적인 견해가 많이 있을 수 있기 때문입니다 (그리고 저도 제 견해가 있을 거예요 🙈). 따라서 핵심적인 부분에 집중하는 것이 좋습니다.
### 테스트
* PR에 **테스트**가 포함되어 있는지 확인하는 데 도움을 주세요.
* PR을 적용하기 전에 테스트가 **실패**하는지 확인하세요. 🚨
* PR을 적용한 후 테스트가 **통과**하는지 확인하세요. ✅
* 많은 PR에는 테스트가 없습니다. 테스트를 추가하도록 **상기**시켜줄 수도 있고, 직접 테스트를 **제안**할 수도 있습니다. 이는 시간이 많이 소요되는 부분 중 하나이며, 그 부분을 많이 도와줄 수 있습니다.
* 그리고 시도한 내용을 댓글로 남겨주세요. 그러면 제가 확인했다는 걸 알 수 있습니다. 🤓
## Pull Request를 만드십시오
Pull Requests를 이용하여 소스코드에 [컨트리뷰트](contributing.md){.internal-link target=\_blank} 할 수 있습니다. 예를 들면 다음과 같습니다:
* 문서에서 발견한 오타를 수정할 때.
* FastAPI 관련 문서, 비디오 또는 팟캐스트를 작성했거나 발견하여 <a href="https://github.com/fastapi/fastapi/edit/master/docs/en/data/external_links.yml" class="external-link" target="_blank">이 파일을 편집하여</a> 공유할 때.
* 해당 섹션의 시작 부분에 링크를 추가해야 합니다.
* 당신의 언어로 [문서 번역하는데](contributing.md#translations){.internal-link target=\_blank} 기여할 때.
* 다른 사람이 작성한 번역을 검토하는 것도 도울 수 있습니다.
* 새로운 문서의 섹션을 제안할 때.
* 기존 문제/버그를 수정할 때.
* 테스트를 반드시 추가해야 합니다.
* 새로운 feature를 추가할 때.
* 테스트를 반드시 추가해야 합니다.
* 관련 문서가 필요하다면 반드시 추가해야 합니다.
## FastAPI 유지 관리에 도움 주기
**FastAPI**의 유지 관리를 도와주세요! 🤓
할 일이 많고, 그 중 대부분은 **여러분**이 할 수 있습니다.
지금 할 수 있는 주요 작업은:
* [GitHub에서 다른 사람들의 질문에 도움 주기](#github_1){.internal-link target=_blank} (위의 섹션을 참조하세요).
* [Pull Request 리뷰하기](#pull-requests){.internal-link target=_blank} (위의 섹션을 참조하세요).
이 두 작업이 **가장 많은 시간을 소모**하는 일입니다. 그것이 FastAPI 유지 관리의 주요 작업입니다.
이 작업을 도와주신다면, **FastAPI 유지 관리에 도움을 주는 것**이며 그것이 **더 빠르고 더 잘 발전하는 것**을 보장하는 것입니다. 🚀
## 채팅에 참여하십시오
👥 <a href="https://discord.gg/VQjSZaeJmf" class="external-link" target="_blank">디스코드 채팅 서버</a> 👥 에 가입하고 FastAPI 커뮤니티에서 다른 사람들과 어울리세요.
/// tip
질문이 있는 경우, <a href="https://github.com/fastapi/fastapi/discussions/new?category=questions" class="external-link" target="_blank">GitHub 디스커션</a> 에서 질문하십시오, [FastAPI Experts](fastapi-people.md#fastapi-experts){.internal-link target=_blank} 의 도움을 받을 가능성이 높습니다.
다른 일반적인 대화에서만 채팅을 사용하십시오.
///
### 질문을 위해 채팅을 사용하지 마십시오
채팅은 더 많은 "자유로운 대화"를 허용하기 때문에, 너무 일반적인 질문이나 대답하기 어려운 질문을 쉽게 질문을 할 수 있으므로, 답변을 받지 못할 수 있습니다.
GitHub 이슈에서의 템플릿은 올바른 질문을 작성하도록 안내하여 더 쉽게 좋은 답변을 얻거나 질문하기 전에 스스로 문제를 해결할 수도 있습니다. 그리고 GitHub에서는 시간이 조금 걸리더라도 항상 모든 것에 답할 수 있습니다. 채팅 시스템에서는 개인적으로 그렇게 할 수 없습니다. 😅
채팅 시스템에서의 대화 또한 GitHub에서 처럼 쉽게 검색할 수 없기 때문에 대화 중에 질문과 답변이 손실될 수 있습니다. 그리고 GitHub 이슈에 있는 것만 [FastAPI Expert](fastapi-people.md#fastapi-experts){.internal-link target=_blank}가 되는 것으로 간주되므로, GitHub 이슈에서 더 많은 관심을 받을 것입니다.
반면, 채팅 시스템에는 수천 명의 사용자가 있기 때문에, 거의 항상 대화 상대를 찾을 가능성이 높습니다. 😄
## 개발자 스폰서가 되십시오
<a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub 스폰서</a> 를 통해 개발자를 경제적으로 지원할 수 있습니다.
감사하다는 말로 커피를 ☕️ 한잔 사줄 수 있습니다. 😄
또한 FastAPI의 실버 또는 골드 스폰서가 될 수 있습니다. 🏅🎉
## FastAPI를 강화하는 도구의 스폰서가 되십시오
문서에서 보았듯이, FastAPI는 Starlette과 Pydantic 라는 거인의 어깨에 타고 있습니다.
다음의 스폰서가 될 수 있습니다
* <a href="https://github.com/sponsors/samuelcolvin" class="external-link" target="_blank">Samuel Colvin (Pydantic)</a>
* <a href="https://github.com/sponsors/encode" class="external-link" target="_blank">Encode (Starlette, Uvicorn)</a>
---
감사합니다! 🚀

11
docs/ko/docs/index.md

@ -11,15 +11,18 @@
<em>FastAPI 프레임워크, 고성능, 간편한 학습, 빠른 코드 작성, 준비된 프로덕션</em>
</p>
<p align="center">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest" target="_blank">
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg" alt="Test">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://codecov.io/gh/fastapi/fastapi" target="_blank">
<img src="https://img.shields.io/codecov/c/github/fastapi/fastapi?color=%2334D058" alt="Coverage">
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">
</a>
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Package version">
</a>
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://img.shields.io/pypi/pyversions/fastapi.svg?color=%2334D058" alt="Supported Python versions">
</a>
</p>
---

273
docs/ko/docs/tutorial/security/oauth2-jwt.md

@ -0,0 +1,273 @@
# 패스워드 해싱을 이용한 OAuth2, JWT 토큰을 사용하는 Bearer 인증
모든 보안 흐름을 구성했으므로, 이제 <abbr title="JSON Web Tokens">JWT</abbr> 토큰과 패스워드 해싱을 사용해 애플리케이션을 안전하게 만들 것입니다.
이 코드는 실제로 애플리케이션에서 패스워드를 해싱하여 DB에 저장하는 등의 작업에 활용할 수 있습니다.
이전 장에 이어서 시작해 봅시다.
## JWT
JWT 는 "JSON Web Tokens" 을 의미합니다.
JSON 객체를 공백이 없는 긴 문자열로 인코딩하는 표준이며, 다음과 같은 형태입니다:
```
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
```
JWT는 암호화되지 않아 누구든지 토큰에서 정보를 복원할 수 있습니다.
하지만 JWT는 서명되어 있습니다. 그래서 자신이 발급한 토큰을 받았을 때, 실제로 자신이 발급한게 맞는지 검증할 수 있습니다.
만료 기간이 일주일인 토큰을 발행했다고 가정해 봅시다. 다음 날 사용자가 토큰을 가져왔을 때, 그 사용자가 시스템에 여전히 로그인되어 있다는 것을 알 수 있습니다.
일주일 뒤에는 토큰이 만료될 것이고, 사용자는 인가되지 않아 새 토큰을 받기 위해 다시 로그인해야 할 것입니다. 만약 사용자(또는 제3자)가 토큰을 수정하거나 만료일을 변경하면, 서명이 일치하지 않기 때문에 알아챌 수 있을 것입니다.
만약 JWT 토큰을 다뤄보고, 작동 방식도 알아보고 싶다면 <a href="https://jwt.io/" class="external-link" target="_blank">https://jwt.io</a> 을 확인하십시오.
## `PyJWT` 설치
파이썬으로 JWT 토큰을 생성하고 검증하려면 `PyJWT` 를 설치해야 합니다.
[가상환경](../../virtual-environments.md){.internal-link target=_blank} 을 만들고 활성화한 다음 `pyjwt` 를 설치하십시오:
<div class="termy">
```console
$ pip install pyjwt
---> 100%
```
</div>
/// info | 참고
RSA나 ECDSA 같은 전자 서명 알고리즘을 사용하려면, `pyjwt[crypto]`라는 암호화 라이브러리 의존성을 설치해야 합니다.
더 자세한 내용은 <a href="https://pyjwt.readthedocs.io/en/latest/installation.html" class="external-link" target="_blank">PyJWT 설치</a> 에서 확인할 수 있습니다.
///
## 패스워드 해싱
"해싱(Hashing)"은 어떤 내용(여기서는 패스워드)을 해석할 수 없는 일련의 바이트 집합(단순 문자열)으로 변환하는 것을 의미합니다.
동일한 내용(똑같은 패스워드)을 해싱하면 동일한 문자열을 얻습니다.
하지만 그 문자열을 다시 패스워드로 되돌릴 수는 없습니다.
### 패스워드를 해싱하는 이유
데이터베이스를 탈취당하더라도, 침입자는 사용자의 평문 패스워드 대신 해시 값만 얻을 수 있습니다.
따라서 침입자는 훔친 사용자 패스워드를 다른 시스템에서 활용할 수 없습니다. (대다수 사용자가 여러 시스템에서 동일한 패스워드를 사용하기 때문에 평문 패스워드가 유출되면 위험합니다.)
## `passlib` 설치
PassLib는 패스워드 해시를 다루는 훌륭한 파이썬 패키지입니다.
많은 안전한 해시 알고리즘과 도구들을 지원합니다.
추천하는 알고리즘은 "Bcrypt"입니다.
[가상환경](../../virtual-environments.md){.internal-link target=_blank} 을 만들고 활성화한 다음 PassLib와 Bcrypt를 설치하십시오:
<div class="termy">
```console
$ pip install "passlib[bcrypt]"
---> 100%
```
</div>
/// tip | 팁
`passlib`를 사용하여, **Django**, **Flask** 의 보안 플러그인이나 다른 도구로 생성한 패스워드를 읽을 수 있도록 설정할 수도 있습니다.
예를 들자면, FastAPI 애플리케이션과 Django 애플리케이션이 같은 데이터베이스에서 데이터를 공유할 수 있습니다. 또는 같은 데이터베이스를 사용하여 Django 애플리케이션을 점진적으로 마이그레이션 할 수도 있습니다.
그리고 사용자는 FastAPI 애플리케이션과 Django 애플리케이션에 동시에 로그인할 수 있습니다.
///
## 패스워드의 해시와 검증
필요한 도구를 `passlib`에서 임포트합니다.
PassLib "컨텍스트(context)"를 생성합니다. 이것은 패스워드를 해싱하고 검증하는데 사용합니다.
/// tip | 팁
PassLib 컨텍스트는 다양한 해싱 알고리즘을 사용할 수 있는 기능을 제공하며, 더 이상 사용이 권장되지 않는 오래된 해싱 알고리즘을 검증하는 기능도 포함되어 있습니다.
예를 들어, 다른 시스템(Django 같은)에서 생성한 패스워드를 읽고 검증할 수 있으며, 새로운 패스워드를 Bcrypt 같은 다른 알고리즘으로 해싱할 수도 있습니다.
그리고 동시에 그런 모든 알고리즘과 호환성을 유지합니다.
///
사용자로부터 받은 패스워드를 해싱하는 유틸리티 함수를 생성합니다.
그리고 받은 패스워드가 저장된 해시와 일치하는지 검증하는 또 다른 유틸리티 함수도 생성합니다.
그리고 사용자를 인증하고 반환하는 또 다른 함수도 생성합니다.
{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,56:57,60:61,70:76] *}
/// note
새로운 (가짜) 데이터베이스 `fake_users_db`를 확인하면, 해시 처리된 패스워드가 어떻게 생겼는지 볼 수 있습니다: `"$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW"`.
///
## JWT 토큰 처리
설치된 모듈을 임포트 합니다.
JWT 토큰 서명에 사용될 임의의 비밀키를 생성합니다.
안전한 임의의 비밀키를 생성하려면 다음 명령어를 사용하십시오:
<div class="termy">
```console
$ openssl rand -hex 32
09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7
```
</div>
그리고 생성한 비밀키를 복사해 변수 `SECRET_KEY`에 대입합니다. (이 예제의 변수 값을 그대로 사용하지 마십시오.)
JWT 토큰을 서명하는 데 사용될 알고리즘을 위한 변수 `ALGORITHM` 을 생성하고 `"HS256"` 으로 설정합니다.
토큰 만료 기간을 위한 변수를 생성합니다.
응답을 위한 토큰 엔드포인트에 사용될 Pydantic 모델을 정의합니다.
새 액세스 토큰을 생성하기 위한 유틸리티 함수를 생성합니다.
{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,79:87] *}
## 의존성 수정
`get_current_user` 함수를 이전과 동일한 토큰을 받도록 수정하되, 이번에는 JWT 토큰을 사용하도록 합니다.
받은 토큰을 디코딩하여 검증한 후 현재 사용자를 반환합니다.
토큰이 유효하지 않다면 HTTP 오류를 반환합니다.
{* ../../docs_src/security/tutorial004_an_py310.py hl[90:107] *}
## `/token` 경로 작업 수정
토큰의 만료 시각을 설정하기 위해 `timedelta` 를 생성합니다.
실제 JWT 액세스 토큰을 생성하여 반환합니다.
{* ../../docs_src/security/tutorial004_an_py310.py hl[118:133] *}
### JWT "주체(subject)" `sub`에 대한 기술 세부 사항
JWT 명세에 따르면 토큰의 주체를 포함하는 `sub`라는 키가 있습니다.
사용 여부는 선택사항이지만, 사용자의 식별 정보를 저장할 수 있으므로 여기서는 이를 사용합니다.
JWT는 사용자를 식별하고 사용자가 API를 직접 사용할 수 있도록 허용하는 것 외에도 다른 용도로 사용될 수도 있습니다.
예를 들어 "자동차"나 "블로그 게시물"을 식별하는 데 사용할 수 있습니다.
그리고 "자동차를 운전하다"나 "블로그 게시물을 수정하다"처럼 해당 엔터티에 대한 권한을 추가할 수 있습니다.
그 후 이 JWT 토큰을 사용자(또는 봇)에게 제공하면, 그들은 계정을 따로 만들 필요 없이 API가 생성한 JWT 토큰만으로 작업(자동차 운전 또는 블로그 게시물 편집)을 수행할 수 있습니다.
이러한 개념을 활용하면 JWT는 훨씬 더 복잡한 시나리오에도 사용할 수 있습니다.
이 경우 여러 엔터티가 동일한 ID를 가질 수 있습니다. 예를 들어 foo라는 ID를 가진 사용자, 자동차, 블로그 게시물이 있을 수 있습니다.
그래서 ID 충돌을 방지하기 위해, 사용자의 JWT 토큰을 생성할 때 접두사로 `sub` 키를 추가할 수 있습니다. 예를 들어 `username:` 을 붙이는 방식입니다. 이 예제에서는 `sub` 값이 `username:johndoe`이 될 수 있습니다.
가장 중요한 점은 `sub` 키는 전체 애플리케이션에서 고유한 식별자가 되어야 하며 문자열이어야 한다는 점입니다.
## 확인해봅시다
서버를 실행하고 문서로 이동하십시오: <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
다음과 같은 사용자 인터페이스를 볼 수 있습니다:
<img src="/img/tutorial/security/image07.png">
이전과 같은 방법으로 애플리케이션에 인증하십시오.
다음 인증 정보를 사용하십시오:
Username: `johndoe`
Password: `secret`
/// check
코드 어디에도 평문 패스워드 "`secret`" 이 없다는 점에 유의하십시오. 해시된 버전만 있습니다.
///
<img src="/img/tutorial/security/image08.png">
`/users/me/` 를 호출하면 다음과 같은 응답을 얻을 수 있습니다:
```JSON
{
"username": "johndoe",
"email": "[email protected]",
"full_name": "John Doe",
"disabled": false
}
```
<img src="/img/tutorial/security/image09.png">
개발자 도구를 열어보면 전송된 데이터에 토큰만 포함된 것을 확인할 수 있습니다. 패스워드는 사용자를 인증하고 액세스 토큰을 받기 위한 첫 번째 요청에만 전송되며, 이후에는 전송되지 않습니다:
<img src="/img/tutorial/security/image10.png">
/// note
`Bearer `로 시작하는 `Authorization` 헤더에 주목하십시오.
///
## `scopes` 의 고급 사용법
OAuth2는 "스코프(scopes)" 라는 개념을 갖고 있습니다.
이를 사용하여 JWT 토큰에 특정 권한 집합을 추가할 수 있습니다.
그 후 이 토큰을 사용자에게 직접 제공하거나 제3자에게 제공하여, 특정 제한사항 하에있는 API와 통신하도록 할 수 있습니다.
**FastAPI** 에서의 사용 방법과 통합 방식은 **심화 사용자 안내서** 에서 자세히 배울 수 있습니다.
## 요약
지금까지 살펴본 내용을 바탕으로, OAuth2와 JWT 같은 표준을 사용하여 안전한 **FastAPI** 애플리케이션을 만들 수 있습니다.
거의 모든 프레임워크에서 보안 처리는 상당히 복잡한 주제입니다.
이를 단순화하는 많은 패키지는 데이터 모델, 데이터베이스, 사용 가능한 기능들에 대해 여러 제약이 있습니다. 그리고 지나치게 단순화하는 일부 패키지들은 심각한 보안 결함을 가질 수도 있습니다.
---
**FastAPI** 는 어떤 데이터베이스, 데이터 모델, 도구도 강요하지 않습니다.
프로젝트에 가장 적합한 것을 선택할 수 있는 유연성을 제공합니다.
그리고 `passlib``PyJWT` 처럼 잘 관리되고 널리 사용되는 패키지들을 바로 사용할 수 있습니다. **FastAPI** 는 외부 패키지 통합을 위해 복잡한 메커니즘이 필요하지 않기 때문입니다.
그러나 유연성, 견고성, 보안성을 해치지 않으면서 과정을 단순화할 수 있는 도구들을 제공합니다.
그리고 OAuth2와 같은 표준 프로토콜을 비교적 간단한 방법으로 구현하고 사용할 수 있습니다.
더 세분화된 권한 체계를 위해 OAuth2의 "스코프"를 사용하는 방법은 **심화 사용자 안내서**에서 더 자세히 배울 수 있습니다. OAuth2의 스코프는 제3자 애플리케이션이 사용자를 대신해 그들의 API와 상호작용하도록 권한을 부여하기 위해, Facebook, Google, GitHub, Microsoft, Twitter 등의 많은 대형 인증 제공업체들이 사용하는 메커니즘입니다.

18
docs/ko/docs/tutorial/security/simple-oauth2.md

@ -32,7 +32,7 @@ OAuth2는 (우리가 사용하고 있는) "패스워드 플로우"을 사용할
* `instagram_basic`은 페이스북/인스타그램에서 사용합니다.
* `https://www.googleapis.com/auth/drive`는 Google에서 사용합니다.
/// 정보
/// info | 정보
OAuth2에서 "범위"는 필요한 특정 권한을 선언하는 문자열입니다.
@ -61,7 +61,7 @@ OAuth2의 경우 문자열일 뿐입니다.
* `scope`는 선택적인 필드로 공백으로 구분된 문자열로 구성된 큰 문자열입니다.
* `grant_type`(선택적으로 사용).
/// 팁
/// tip |
OAuth2 사양은 실제로 `password`라는 고정 값이 있는 `grant_type` 필드를 *요구*하지만 `OAuth2PasswordRequestForm`은 이를 강요하지 않습니다.
@ -72,7 +72,7 @@ OAuth2 사양은 실제로 `password`라는 고정 값이 있는 `grant_type`
* `client_id`(선택적으로 사용) (예제에서는 필요하지 않습니다).
* `client_secret`(선택적으로 사용) (예제에서는 필요하지 않습니다).
/// 정보
/// info | 정보
`OAuth2PasswordRequestForm``OAuth2PasswordBearer`와 같이 **FastAPI**에 대한 특수 클래스가 아닙니다.
@ -86,7 +86,7 @@ OAuth2 사양은 실제로 `password`라는 고정 값이 있는 `grant_type`
### 폼 데이터 사용하기
/// 팁
/// tip |
종속성 클래스 `OAuth2PasswordRequestForm`의 인스턴스에는 공백으로 구분된 긴 문자열이 있는 `scope` 속성이 없고 대신 전송된 각 범위에 대한 실제 문자열 목록이 있는 `scopes` 속성이 있습니다.
@ -126,7 +126,7 @@ OAuth2 사양은 실제로 `password`라는 고정 값이 있는 `grant_type`
따라서 해커는 다른 시스템에서 동일한 암호를 사용하려고 시도할 수 없습니다(많은 사용자가 모든 곳에서 동일한 암호를 사용하므로 이는 위험할 수 있습니다).
//// tab | P파이썬 3.7 이상
//// tab | 파이썬 3.7 이상
{* ../../docs_src/security/tutorial003.py hl[80:83] *}
@ -150,7 +150,7 @@ UserInDB(
)
```
/// 정보
/// info | 정보
`**user_dict`에 대한 자세한 설명은 [**추가 모델** 문서](../extra-models.md#about-user_indict){.internal-link target=_blank}를 다시 읽어봅시다.
@ -166,7 +166,7 @@ UserInDB(
이 간단한 예제에서는 완전히 안전하지 않고, 동일한 `username`을 토큰으로 반환합니다.
/// 팁
/// tip |
다음 장에서는 패스워드 해싱 및 <abbr title="JSON Web Tokens">JWT</abbr> 토큰을 사용하여 실제 보안 구현을 볼 수 있습니다.
@ -176,7 +176,7 @@ UserInDB(
{* ../../docs_src/security/tutorial003.py hl[85] *}
/// 팁
/// tip |
사양에 따라 이 예제와 동일하게 `access_token``token_type`이 포함된 JSON을 반환해야 합니다.
@ -202,7 +202,7 @@ UserInDB(
{* ../../docs_src/security/tutorial003.py hl[58:66,69:72,90] *}
/// 정보
/// info | 정보
여기서 반환하는 값이 `Bearer`인 추가 헤더 `WWW-Authenticate`도 사양의 일부입니다.

2
docs/nl/docs/index.md

@ -12,7 +12,7 @@
</p>
<p align="center">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">

11
docs/pl/docs/index.md

@ -11,15 +11,18 @@
<em>FastAPI to szybki, prosty w nauce i gotowy do użycia w produkcji framework</em>
</p>
<p align="center">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest" target="_blank">
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg" alt="Test">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://codecov.io/gh/fastapi/fastapi" target="_blank">
<img src="https://img.shields.io/codecov/c/github/fastapi/fastapi?color=%2334D058" alt="Coverage">
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">
</a>
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Package version">
</a>
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://img.shields.io/pypi/pyversions/fastapi.svg?color=%2334D058" alt="Supported Python versions">
</a>
</p>
---

2
docs/pt/docs/index.md

@ -12,7 +12,7 @@
</p>
<p align="center">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">

48
docs/ru/docs/advanced/response-cookies.md

@ -0,0 +1,48 @@
# Cookies в ответе
## Использование параметра `Response`
Вы можете объявить параметр типа `Response` в вашей функции эндпоинта.
Затем установить cookies в этом временном объекте ответа.
{* ../../docs_src/response_cookies/tutorial002.py hl[1, 8:9] *}
После этого можно вернуть любой объект, как и раньше (например, `dict`, объект модели базы данных и так далее).
Если вы указали `response_model`, он всё равно будет использоваться для фильтрации и преобразования возвращаемого объекта.
**FastAPI** извлечет cookies (а также заголовки и коды состояния) из временного ответа и включит их в окончательный ответ, содержащий ваше возвращаемое значение, отфильтрованное через `response_model`.
Вы также можете объявить параметр типа Response в зависимостях и устанавливать cookies (и заголовки) там.
## Возвращение `Response` напрямую
Вы также можете установить cookies, если возвращаете `Response` напрямую в вашем коде.
Для этого создайте объект `Response`, как описано в разделе [Возвращение ответа напрямую](response-directly.md){.target=_blank}.
Затем установите cookies и верните этот объект:
{* ../../docs_src/response_cookies/tutorial001.py hl[10:12] *}
/// tip | Примечание
Имейте в виду, что если вы возвращаете ответ напрямую, вместо использования параметра `Response`, **FastAPI** отправит его без дополнительной обработки.
Убедитесь, что ваши данные имеют корректный тип. Например, они должны быть совместимы с JSON, если вы используете `JSONResponse`.
Также убедитесь, что вы не отправляете данные, которые должны были быть отфильтрованы через `response_model`.
///
### Дополнительная информация
/// note | Технические детали
Вы также можете использовать `from starlette.responses import Response` или `from starlette.responses import JSONResponse`.
**FastAPI** предоставляет `fastapi.responses`, которые являются теми же объектами, что и `starlette.responses`, просто для удобства. Однако большинство доступных типов ответов поступает непосредственно из **Starlette**.
Для установки заголовков и cookies `Response` используется часто, поэтому **FastAPI** также предоставляет его через `fastapi.responses`.
///
Чтобы увидеть все доступные параметры и настройки, ознакомьтесь с <a href="https://www.starlette.io/responses/#set-cookie" class="external-link" target="_blank">документацией Starlette</a>.

6
docs/ru/docs/index.md

@ -12,10 +12,10 @@
</p>
<p align="center">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://codecov.io/gh/fastapi/fastapi" target="_blank">
<img src="https://img.shields.io/codecov/c/github/fastapi/fastapi?color=%2334D058" alt="Coverage">
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">
</a>
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Package version">

74
docs/ru/docs/tutorial/middleware.md

@ -0,0 +1,74 @@
# Middleware (Промежуточный слой)
Вы можете добавить промежуточный слой (middleware) в **FastAPI** приложение.
"Middleware" это функция, которая выполняется с каждым запросом до его обработки какой-либо конкретной *операцией пути*.
А также с каждым ответом перед его возвращением.
* Она принимает каждый поступающий **запрос**.
* Может что-то сделать с этим **запросом** или выполнить любой нужный код.
* Затем передает **запрос** для последующей обработки (какой-либо *операцией пути*).
* Получает **ответ** (от *операции пути*).
* Может что-то сделать с этим **ответом** или выполнить любой нужный код.
* И возвращает **ответ**.
/// note | Технические детали
Если у вас есть зависимости с `yield`, то код выхода (код после `yield`) будет выполняться *после* middleware.
Если у вас имеются некие фоновые задачи (см. документацию), то они будут запущены после middleware.
///
## Создание middleware
Для создания middleware используйте декоратор `@app.middleware("http")`.
Функция middleware получает:
* `request` (объект запроса).
* Функцию `call_next`, которая получает `request` в качестве параметра.
* Эта функция передаёт `request` соответствующей *операции пути*.
* Затем она возвращает ответ `response`, сгенерированный *операцией пути*.
* Также имеется возможность видоизменить `response`, перед тем как его вернуть.
{* ../../docs_src/middleware/tutorial001.py hl[8:9,11,14] *}
/// tip | Примечание
Имейте в виду, что можно добавлять свои собственные заголовки <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">при помощи префикса 'X-'</a>.
Если же вы хотите добавить собственные заголовки, которые клиент сможет увидеть в браузере, то вам потребуется добавить их в настройки CORS ([CORS (Cross-Origin Resource Sharing)](cors.md){.internal-link target=_blank}), используя параметр `expose_headers`, см. документацию <a href="https://www.starlette.io/middleware/#corsmiddleware" class="external-link" target="_blank">Starlette's CORS docs</a>.
///
/// note | Технические детали
Вы также можете использовать `from starlette.requests import Request`.
**FastAPI** предоставляет такой доступ для удобства разработчиков. Но, на самом деле, это `Request` из Starlette.
///
### До и после `response`
Вы можете добавить код, использующий `request` до передачи его какой-либо *операции пути*.
А также после формирования `response`, до того, как вы его вернёте.
Например, вы можете добавить собственный заголовок `X-Process-Time`, содержащий время в секундах, необходимое для обработки запроса и генерации ответа:
{* ../../docs_src/middleware/tutorial001.py hl[10,12:13] *}
/// tip | Примечание
Мы используем <a href="https://docs.python.org/3/library/time.html#time.perf_counter" class="external-link" target="_blank">`time.perf_counter()`</a> вместо `time.time()` для обеспечения большей точности наших примеров. 🤓
///
## Другие middleware
О других middleware вы можете узнать больше в разделе [Advanced User Guide: Advanced Middleware](../advanced/middleware.md){.internal-link target=_blank}.
В следующем разделе вы можете прочитать, как настроить <abbr title="Cross-Origin Resource Sharing">CORS</abbr> с помощью middleware.

28
docs/ru/docs/tutorial/query-params-str-validations.md

@ -291,22 +291,6 @@ q: Union[str, None] = Query(default=None, min_length=3)
{* ../../docs_src/query_params_str_validations/tutorial006_an_py39.py hl[9] *}
### Обязательный параметр с Ellipsis (`...`)
Альтернативный способ указать обязательность параметра запроса - это указать параметр `default` через многоточие `...`:
{* ../../docs_src/query_params_str_validations/tutorial006b_an_py39.py hl[9] *}
/// info | Дополнительная информация
Если вы ранее не сталкивались с `...`: это специальное значение, <a href="https://docs.python.org/3/library/constants.html#Ellipsis" class="external-link" target="_blank">часть языка Python и называется "Ellipsis"</a>.
Используется в Pydantic и FastAPI для определения, что значение требуется обязательно.
///
Таким образом, **FastAPI** определяет, что параметр является обязательным.
### Обязательный параметр с `None`
Вы можете определить, что параметр может принимать `None`, но всё ещё является обязательным. Это может потребоваться для того, чтобы пользователи явно указали параметр, даже если его значение будет `None`.
@ -321,18 +305,6 @@ Pydantic, мощь которого используется в FastAPI для
///
### Использование Pydantic's `Required` вместо Ellipsis (`...`)
Если вас смущает `...`, вы можете использовать `Required` из Pydantic:
{* ../../docs_src/query_params_str_validations/tutorial006d_an_py39.py hl[4,10] *}
/// tip | Подсказка
Запомните, когда вам необходимо объявить query-параметр обязательным, вы можете просто не указывать параметр `default`. Таким образом, вам редко придётся использовать `...` или `Required`.
///
## Множество значений для query-параметра
Для query-параметра `Query` можно указать, что он принимает список значений (множество значений).

2
docs/tr/docs/index.md

@ -12,7 +12,7 @@
</p>
<p align="center">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">

2
docs/uk/docs/index.md

@ -6,7 +6,7 @@
</p>
<p align="center">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">

170
docs/uk/docs/tutorial/body-multiple-params.md

@ -0,0 +1,170 @@
# Тіло запиту - Декілька параметрів
Тепер, коли ми розглянули використання `Path` та `Query`, розгляньмо більш просунуті способи оголошення тіла запиту в **FastAPI**.
## Змішування `Path`, `Query` та параметрів тіла запиту
По-перше, звісно, Ви можете вільно змішувати оголошення параметрів `Path`, `Query` та тіла запиту, і **FastAPI** правильно їх обробить.
Також Ви можете оголосити параметри тіла як необов’язкові, встановивши для них значення за замовчуванням `None`:
{* ../../docs_src/body_multiple_params/tutorial001_an_py310.py hl[18:20] *}
/// note | Примітка
Зверніть увагу, що в цьому випадку параметр `item`, який береться з тіла запиту, є необов'язковим, оскільки має значення за замовчуванням `None`.
///
## Декілька параметрів тіла запиту
У попередньому прикладі *операція шляху* очікувала JSON з атрибутами `Item`, наприклад:
```JSON
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
}
```
Але Ви також можете оголосити декілька параметрів тіла, наприклад `item` та `user`:
{* ../../docs_src/body_multiple_params/tutorial002_py310.py hl[20] *}
У цьому випадку **FastAPI** розпізнає, що є кілька параметрів тіла (два параметри є моделями Pydantic).
Тому він використає назви параметрів як ключі (назви полів) у тілі запиту, очікуючи:
```JSON
{
"item": {
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
},
"user": {
"username": "dave",
"full_name": "Dave Grohl"
}
}
```
/// note | Примітка
Зверніть увагу, що хоча `item` оголошено, так само як і раніше, тепер він очікується в тілі під ключем `item`.
///
**FastAPI** автоматично конвертує дані із запиту таким чином, щоб параметр `item` отримав свій вміст, і те ж саме стосується `user`.
Він виконає валідацію складених даних і задокументує їх відповідним чином у схемі OpenAPI та в автоматичній документації.
## Одиничні значення в тілі запиту
Так само як є `Query` і `Path` для визначення додаткових даних для параметрів запиту та шляху, **FastAPI** надає еквівалентний `Body`.
Наприклад, розширюючи попередню модель, Ви можете вирішити додати ще один ключ `importance` в те ж саме тіло запиту разом із `item` і `user`.
Якщо Ви оголосите його як є, то, оскільки це одиничне значення, **FastAPI** припускатиме, що це параметр запиту (query parameter).
Але Ви можете вказати **FastAPI** обробляти його як інший ключ тіла (body key), використовуючи `Body`:
{* ../../docs_src/body_multiple_params/tutorial003_an_py310.py hl[23] *}
У цьому випадку **FastAPI** очікуватиме тіло запиту у такому вигляді:
```JSON
{
"item": {
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
},
"user": {
"username": "dave",
"full_name": "Dave Grohl"
},
"importance": 5
}
```
Знову ж таки, **FastAPI** конвертуватиме типи даних, перевірятиме їх, створюватиме документацію тощо.
## Декілька body та query параметрів
Звісно, Ви можете оголошувати додаткові query параметри запиту, коли це необхідно, на додаток до будь-яких параметрів тіла запиту.
Оскільки за замовчуванням окремі значення інтерпретуються як параметри запиту, Вам не потрібно явно додавати `Query`, можна просто використати:
```Python
q: Union[str, None] = None
```
Або в Python 3.10 та вище:
```Python
q: str | None = None
```
Наприклад:
{* ../../docs_src/body_multiple_params/tutorial004_an_py310.py hl[28] *}
/// info | Інформація
`Body` також має ті самі додаткові параметри валідації та метаданих, що й `Query`, `Path` та інші, які Ви побачите пізніше.
///
## Вкладений поодинокий параметр тіла запиту
Припустимо, у вас є лише один параметр тіла запиту `item` з моделі Pydantic `Item`.
За замовчуванням **FastAPI** очікуватиме, що тіло запиту міститиме вміст безпосередньо.
Але якщо Ви хочете, щоб він очікував JSON з ключем `item`, а всередині — вміст моделі (так, як це відбувається при оголошенні додаткових параметрів тіла), Ви можете використати спеціальний параметр `Body``embed`:
```Python
item: Item = Body(embed=True)
```
як у прикладі:
{* ../../docs_src/body_multiple_params/tutorial005_an_py310.py hl[17] *}
У цьому випадку **FastAPI** очікуватиме тіло запиту такого вигляду:
```JSON hl_lines="2"
{
"item": {
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
}
}
```
замість:
```JSON
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
}
```
## Підсумок
Ви можете додавати кілька параметрів тіла до Вашої *функції операції шляху* (*path operation function*), навіть якщо запит може мати лише одне тіло.
Але **FastAPI** обробить це, надасть Вам потрібні дані у функції, перевірить їх та задокументує коректну схему в *операції шляху*.
Також Ви можете оголошувати окремі значення, які будуть отримані як частина тіла запиту.
Крім того, Ви можете вказати **FastAPI** вбудовувати тіло в ключ, навіть якщо оголошено лише один параметр.

245
docs/uk/docs/tutorial/body-nested-models.md

@ -0,0 +1,245 @@
# Тіло запиту - Вкладені моделі
З **FastAPI** Ви можете визначати, перевіряти, документувати та використовувати моделі, які можуть бути вкладені на будь-яку глибину (завдяки Pydantic).
## Поля списку
Ви можете визначити атрибут як підтип. Наприклад, Python-список (`list`):
{* ../../docs_src/body_nested_models/tutorial001_py310.py hl[12] *}
Це зробить `tags` списком, хоча не визначається тип елементів списку.
## Поля списку з параметром типу
Але Python має специфічний спосіб оголошення списків з внутрішніми типами або "параметрами типу":
### Імпортуємо `List` з модуля typing
У Python 3.9 і вище можна використовувати стандартний `list` для оголошення таких типів, як ми побачимо нижче. 💡
Але в Python версії до 3.9 (від 3.6 і вище) спочатку потрібно імпортувати `List` з модуля стандартної бібліотеки Python `typing`:
{* ../../docs_src/body_nested_models/tutorial002.py hl[1] *}
### Оголошення `list` з параметром типу
Щоб оголосити типи з параметрами типу (внутрішніми типами), такими як `list`, `dict`, `tuple`:
* Якщо Ви використовуєте версію Python до 3.9, імпортуйте їх відповідну версію з модуля `typing`.
* Передайте внутрішні типи як "параметри типу", використовуючи квадратні дужки: `[` and `]`.
У Python 3.9 це буде виглядати так:
```Python
my_list: list[str]
```
У версіях Python до 3.9 це виглядає так:
```Python
from typing import List
my_list: List[str]
```
Це стандартний синтаксис Python для оголошення типів.
Використовуйте той самий стандартний синтаксис для атрибутів моделей з внутрішніми типами.
Отже, у нашому прикладі, ми можемо зробити `tags` саме "списком рядків":
{* ../../docs_src/body_nested_models/tutorial002_py310.py hl[12] *}
## Типи множин
Але потім ми подумали, що теги не повинні повторюватися, вони, ймовірно, повинні бути унікальними рядками.
І Python має спеціальний тип даних для множин унікальних елементів — це `set`.
Тому ми можемо оголосити `tags` як множину рядків:
{* ../../docs_src/body_nested_models/tutorial003_py310.py hl[12] *}
Навіть якщо Ви отримаєте запит з дубльованими даними, він буде перетворений у множину унікальних елементів.
І коли Ви будете виводити ці дані, навіть якщо джерело містить дублікати, вони будуть виведені як множина унікальних елементів.
І це буде анотовано/документовано відповідно.
## Вкладені моделі
Кожен атрибут моделі Pydantic має тип.
Але цей тип сам може бути іншою моделлю Pydantic.
Отже, Ви можете оголосити глибоко вкладені JSON "об'єкти" з конкретними іменами атрибутів, типами та перевірками.
Усе це, вкладене без обмежень.
### Визначення підмоделі
Наприклад, ми можемо визначити модель `Image`:
{* ../../docs_src/body_nested_models/tutorial004_py310.py hl[7:9] *}
### Використання підмоделі як типу
А потім ми можемо використовувати її як тип атрибута:
{* ../../docs_src/body_nested_models/tutorial004_py310.py hl[18] *}
Це означатиме, що **FastAPI** очікуватиме тіло запиту такого вигляду:
```JSON
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2,
"tags": ["rock", "metal", "bar"],
"image": {
"url": "http://example.com/baz.jpg",
"name": "The Foo live"
}
}
```
Завдяки такій декларації у **FastAPI** Ви отримуєте:
* Підтримку в редакторі (автозавершення тощо), навіть для вкладених моделей
* Конвертацію даних
* Валідацію даних
* Автоматичну документацію
## Спеціальні типи та валідація
Окрім звичайних типів, таких як `str`, `int`, `float`, та ін. Ви можете використовувати складніші типи, які наслідують `str`.
Щоб побачити всі доступні варіанти, ознайомтеся з оглядом <a href="https://docs.pydantic.dev/latest/concepts/types/" class="external-link" target="_blank">типів у Pydantic</a>. Деякі приклади будуть у наступних розділах.
Наприклад, у моделі `Image` є поле `url`, тому ми можемо оголосити його як `HttpUrl` від Pydantic замість `str`:
{* ../../docs_src/body_nested_models/tutorial005_py310.py hl[2,8] *}
Рядок буде перевірено як дійсну URL-адресу і задокументовано в JSON Schema / OpenAPI як URL.
## Атрибути зі списками підмоделей
У Pydantic Ви можете використовувати моделі як підтипи для `list`, `set` тощо:
{* ../../docs_src/body_nested_models/tutorial006_py310.py hl[18] *}
Це означає, що **FastAPI** буде очікувати (конвертувати, валідувати, документувати тощо) JSON тіло запиту у вигляді:
```JSON hl_lines="11"
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2,
"tags": [
"rock",
"metal",
"bar"
],
"images": [
{
"url": "http://example.com/baz.jpg",
"name": "The Foo live"
},
{
"url": "http://example.com/dave.jpg",
"name": "The Baz"
}
]
}
```
/// info | Інформація
Зверніть увагу, що тепер ключ `images` містить список об'єктів зображень.
///
## Глибоко вкладені моделі
Ви можете визначати вкладені моделі довільної глибини:
{* ../../docs_src/body_nested_models/tutorial007_py310.py hl[7,12,18,21,25] *}
/// info | Інформація
Зверніть увагу, що в моделі `Offer` є список `Item`ів, які, своєю чергою, можуть мати необов'язковий список `Image`ів.
///
## Тіла запитів, що складаються зі списків
Якщо верхній рівень JSON тіла, яке Ви очікуєте, є JSON `масивом` (у Python — `list`), Ви можете оголосити тип у параметрі функції, як і в моделях Pydantic:
```Python
images: List[Image]
```
або в Python 3.9 і вище:
```Python
images: list[Image]
```
наприклад:
{* ../../docs_src/body_nested_models/tutorial008_py39.py hl[13] *}
## Підтримка в редакторі всюди
Ви отримаєте підтримку в редакторі всюди.
Навіть для елементів у списках:
<img src="/img/tutorial/body-nested-models/image01.png">
Ви не змогли б отримати таку підтримку в редакторі, якби працювали напряму зі `dict`, а не з моделями Pydantic.
Але Вам не потрібно турбуватися про це: вхідні dict'и автоматично конвертуються, а вихідні дані автоматично перетворюються в JSON.
## Тіла з довільними `dict`
Ви також можете оголосити тіло як `dict` з ключами одного типу та значеннями іншого типу.
Це корисно, якщо Ви не знаєте наперед, які імена полів будуть дійсними (як у випадку з моделями Pydantic).
Це буде корисно, якщо Ви хочете приймати ключі, які заздалегідь невідомі.
---
Це також зручно, якщо Ви хочете мати ключі іншого типу (наприклад, `int`).
Ось що ми розглянемо далі.
У цьому випадку Ви можете приймати будь-який `dict`, якщо його ключі — це `int`, а значення — `float`:
{* ../../docs_src/body_nested_models/tutorial009_py39.py hl[7] *}
/// tip | Порада
Майте на увазі, що в JSON тілі ключі можуть бути лише рядками (`str`).
Але Pydantic автоматично конвертує дані.
Це означає, що навіть якщо клієнти вашого API надсилатимуть ключі у вигляді рядків, якщо вони містять цілі числа, Pydantic конвертує їх і проведе валідацію.
Тобто `dict`, який Ви отримаєте як `weights`, матиме ключі типу `int` та значення типу `float`.
///
## Підсумок
З **FastAPI** Ви маєте максимальну гнучкість завдяки моделям Pydantic, зберігаючи при цьому код простим, коротким та елегантним.
А також отримуєте всі переваги:
* Підтримка в редакторі (автодоповнення всюди!)
* Конвертація даних (парсинг/сериалізація)
* Валідація даних
* Документація схем
* Автоматичне створення документації

112
docs/uk/docs/tutorial/debugging.md

@ -0,0 +1,112 @@
# Налагодження (Debugging)
Ви можете під'єднати дебагер у Вашому редакторі коду, наприклад, у Visual Studio Code або PyCharm.
## Виклик `uvicorn`
У Вашому FastAPI-додатку імпортуйте та запустіть `uvicorn` безпосередньо:
{* ../../docs_src/debugging/tutorial001.py hl[1,15] *}
### Про `__name__ == "__main__"`
Головна мета використання `__name__ == "__main__"` — це забезпечення виконання певного коду тільки тоді, коли файл запускається безпосередньо:
<div class="termy">
```console
$ python myapp.py
```
</div>
але не виконується при його імпорті в інший файл, наприклад:
```Python
from myapp import app
```
#### Детальніше
Припустимо, Ваш файл називається `myapp.py`.
Якщо Ви запустите його так:
<div class="termy">
```console
$ python myapp.py
```
</div>
тоді внутрішня змінна `__name__`, яка створюється автоматично Python, матиме значення `"__main__"`.
Отже, цей блок коду:
```Python
uvicorn.run(app, host="0.0.0.0", port=8000)
```
буде виконаний.
---
Це не станеться, якщо Ви імпортуєте цей модуль (файл).
Якщо у Вас є інший файл, наприклад `importer.py`, з наступним кодом:
```Python
from myapp import app
# Додатковий код
```
У цьому випадку автоматично створена змінна у файлі `myapp.py` не матиме значення змінної `__name__` як `"__main__"`.
Отже, рядок:
```Python
uvicorn.run(app, host="0.0.0.0", port=8000)
```
не буде виконано.
/// info | Інформація
Більш детальну інформацію можна знайти в <a href="https://docs.python.org/3/library/__main__.html" class="external-link" target="_blank">офіційній документації Python</a>.
///
## Запуск коду з вашим дебагером
Оскільки Ви запускаєте сервер Uvicorn безпосередньо з Вашого коду, Ви можете запустити вашу Python програму (ваш FastAPI додаток) безпосередньо з дебагера.
---
Наприклад, у Visual Studio Code Ви можете:
* Перейдіть на вкладку "Debug".
* Натисніть "Add configuration...".
* Виберіть "Python"
* Запустіть дебагер з опцією "`Python: Current File (Integrated Terminal)`".
Це запустить сервер з Вашим **FastAPI** кодом, зупиниться на точках зупину тощо.
Ось як це може виглядати:
<img src="/img/tutorial/debugging/image01.png">
---
Якщо Ви використовуєте PyCharm, ви можете:
* Відкрити меню "Run".
* Вибрати опцію "Debug...".
* Потім з'явиться контекстне меню.
* Вибрати файл для налагодження (у цьому випадку, `main.py`).
Це запустить сервер з Вашим **FastAPI** кодом, зупиниться на точках зупину тощо.
Ось як це може виглядати:
<img src="/img/tutorial/debugging/image02.png">

91
docs/uk/docs/tutorial/header-params.md

@ -0,0 +1,91 @@
# Header-параметри
Ви можете визначати параметри заголовків, так само як визначаєте `Query`, `Path` і `Cookie` параметри.
## Імпорт `Header`
Спочатку імпортуйте `Header`:
{* ../../docs_src/header_params/tutorial001_an_py310.py hl[3] *}
## Оголошення параметрів `Header`
Потім оголосіть параметри заголовків, використовуючи ту ж структуру, що й для `Path`, `Query` та `Cookie`.
Ви можете визначити значення за замовчуванням, а також усі додаткові параметри валідації або анотації:
{* ../../docs_src/header_params/tutorial001_an_py310.py hl[9] *}
/// note | Технічні деталі
`Header`є "сестринським" класом для `Path`, `Query` і `Cookie`. Він також успадковується від загального класу `Param`.
Але пам’ятайте, що при імпорті `Query`, `Path`, `Header` та інших із `fastapi`, то насправді вони є функціями, які повертають спеціальні класи.
///
/// info | Інформація
Щоб оголосити заголовки, потрібно використовувати `Header`, інакше параметри будуть інтерпретуватися як параметри запиту.
///
## Автоматичне перетворення
`Header` має додатковий функціонал порівняно з `Path`, `Query` та `Cookie`.
Більшість стандартних заголовків розділяються символом «дефіс», також відомим як «мінус» (`-`).
Але змінна, така як `user-agent`, є недійсною в Python.
Тому, за замовчуванням, `Header` автоматично перетворює символи підкреслення (`_`) на дефіси (`-`) для отримання та документування заголовків.
Оскільки заголовки HTTP не чутливі до регістру, Ви можете використовувати стандартний стиль Python ("snake_case").
Тому Ви можете використовувати `user_agent`, як зазвичай у коді Python, замість того щоб писати з великої літери, як `User_Agent` або щось подібне.
Якщо Вам потрібно вимкнути автоматичне перетворення підкреслень у дефіси, встановіть `convert_underscores` в `Header` значення `False`:
{* ../../docs_src/header_params/tutorial002_an_py310.py hl[10] *}
/// warning | Увага
Перед тим як встановити значення `False` для `convert_underscores` пам’ятайте, що деякі HTTP-проксі та сервери не підтримують заголовки з підкресленнями.
///
## Дубльовані заголовки
Можливо отримати дубльовані заголовки, тобто той самий заголовок із кількома значеннями.
Це можна визначити, використовуючи список у типізації параметра.
Ви отримаєте всі значення дубльованого заголовка у вигляді `list` у Python.
Наприклад, щоб оголосити заголовок `X-Token`, який може з’являтися більше ніж один раз:
{* ../../docs_src/header_params/tutorial003_an_py310.py hl[9] *}
Якщо Ви взаємодієте з цією операцією шляху, надсилаючи два HTTP-заголовки, наприклад:
```
X-Token: foo
X-Token: bar
```
Відповідь буде така:
```JSON
{
"X-Token values": [
"bar",
"foo"
]
}
```
## Підсумок
Оголошуйте заголовки за допомогою `Header`, використовуючи той самий підхід, що й для `Query`, `Path` та `Cookie`.
Не хвилюйтеся про підкреслення у змінних — **FastAPI** автоматично конвертує їх.

261
docs/uk/docs/tutorial/path-params.md

@ -0,0 +1,261 @@
# Path Параметри
Ви можете визначити "параметри" або "змінні" шляху, використовуючи синтаксис форматованих рядків:
{* ../../docs_src/path_params/tutorial001.py hl[6:7] *}
Значення параметра шляху `item_id` передається у функцію як аргумент `item_id`.
Якщо запустити цей приклад та перейти за посиланням <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a>, то отримаємо таку відповідь:
```JSON
{"item_id":"foo"}
```
## Path параметри з типами
Ви можете визначити тип параметра шляху у функції, використовуючи стандартні анотації типів Python:
{* ../../docs_src/path_params/tutorial002.py hl[7] *}
У такому випадку `item_id` визначається як `int`.
/// check | Примітка
Це дасть можливість підтримки редактора всередині функції з перевірками помилок, автодоповнення тощо.
///
## <abbr title="або: серіалізація, парсинг, маршалізація">Перетворення</abbr> даних
Якщо запустити цей приклад і перейти за посиланням <a href="http://127.0.0.1:8000/items/3" class="external-link" target="_blank">http://127.0.0.1:8000/items/3</a>, то отримаєте таку відповідь:
```JSON
{"item_id":3}
```
/// check | Примітка
Зверніть увагу, що значення, яке отримала (і повернула) ваша функція, — це `3`. Це Python `int`, а не рядок `"3"`.
Отже, з таким оголошенням типу **FastAPI** автоматично виконує <abbr title="перетворення рядка, що надходить із HTTP-запиту, у типи даних Python">"парсинг"</abbr> запитів.
///
## <abbr title="Або валідація">Перевірка</abbr> даних
Якщо ж відкрити у браузері посилання <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a>, то побачимо цікаву HTTP-помилку:
```JSON
{
"detail": [
{
"type": "int_parsing",
"loc": [
"path",
"item_id"
],
"msg": "Input should be a valid integer, unable to parse string as an integer",
"input": "foo",
"url": "https://errors.pydantic.dev/2.1/v/int_parsing"
}
]
}
```
тому що параметр шляху має значення `"foo"`, яке не є типом `int`.
Таку саму помилку отримаємо, якщо передати `float` замість `int`, як бачимо, у цьому прикладі: <a href="http://127.0.0.1:8000/items/4.2" class="external-link" target="_blank">http://127.0.0.1:8000/items/4.2</a>
/// check | Примітка
Отже, **FastAPI** надає перевірку типів з таким самим оголошенням типу в Python.
Зверніть увагу, що помилка також чітко вказує саме на те місце, де валідація не пройшла.
Це неймовірно корисно під час розробки та дебагінгу коду, що взаємодіє з вашим API.
///
## Документація
Тепер коли відкриєте свій браузер за посиланням <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>, то побачите автоматично згенеровану, інтерактивну API-документацію:
<img src="/img/tutorial/path-params/image01.png">
/// check | Примітка
Знову ж таки, лише з цим самим оголошенням типу в Python, FastAPI надає вам автоматичну, інтерактивну документацію (з інтеграцією Swagger UI).
Зверніть увагу, що параметр шляху оголошений як ціле число.
///
## Переваги стандартизації, альтернативна документація
І оскільки згенерована схема відповідає стандарту <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md" class="external-link" target="_blank">OpenAPI</a>, існує багато сумісних інструментів.
З цієї причини FastAPI також надає альтернативну документацію API (використовуючи ReDoc), до якої можна отримати доступ за посиланням <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>:
<img src="/img/tutorial/path-params/image02.png">
Таким чином, існує багато сумісних інструментів, включаючи інструменти для генерації коду для багатьох мов.
## Pydantic
Вся валідація даних виконується за лаштунками за допомогою <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a>, тому Ви отримуєте всі переваги від його використання. І можете бути впевнені, що все в надійних руках.
Ви можете використовувати ті самі оголошення типів з `str`, `float`, `bool` та багатьма іншими складними типами даних.
Декілька з них будуть розглянуті в наступних розділах посібника.
## Порядок має значення
При створенні *операцій шляху* можуть виникати ситуації, коли шлях фіксований.
Наприклад, `/users/me`. Припустимо, що це шлях для отримання даних про поточного користувача.
А також у вас може бути шлях `/users/{user_id}`, щоб отримати дані про конкретного користувача за його ID.
Оскільки *операції шляху* оцінюються по черзі, Ви повинні переконатися, що шлях для `/users/me` оголошений перед шляхом для `/users/{user_id}`:
{* ../../docs_src/path_params/tutorial003.py hl[6,11] *}
Інакше шлях для `/users/{user_id}` також буде відповідати для `/users/me`, "вважаючи", що він отримує параметр `user_id` зі значенням `"me"`.
Аналогічно, Ви не можете оголосити операцію шляху:
{* ../../docs_src/path_params/tutorial003b.py hl[6,11] *}
Перша операція буде завжди використовуватися, оскільки шлях збігається першим.
## Попередньо визначені значення
Якщо у вас є *операція шляху*, яка приймає *параметр шляху*, але Ви хочете, щоб можливі допустимі значення *параметра шляху* були попередньо визначені, Ви можете використати стандартний Python <abbr title="перелічення">Enum</abbr>.
### Створення класу `Enum`
Імпортуйте `Enum` і створіть підклас, що наслідується від `str` та `Enum`.
Наслідуючи від `str`, документація API зможе визначити, що значення повинні бути типу `string`, і правильно їх відобразить.
Після цього створіть атрибути класу з фіксованими значеннями, які будуть доступними допустимими значеннями:
{* ../../docs_src/path_params/tutorial005.py hl[1,6:9] *}
/// info | Додаткова інформація
<a href="https://docs.python.org/3/library/enum.html" class="external-link" target="_blank">Перелічення (або enums) доступні в Python</a> починаючи з версії 3.4.
///
/// tip | Порада
Якщо вам цікаво, "AlexNet", "ResNet" та "LeNet" — це просто назви ML моделей <abbr title="Технічно, архітектури Deep Learning моделей">Machine Learning</abbr>.
///
### Оголосіть *параметр шляху*
Потім створіть *параметр шляху* з анотацією типу, використовуючи створений вами клас enum (`ModelName`):
{* ../../docs_src/path_params/tutorial005.py hl[16] *}
### Перевірка документації
Оскільки доступні значення для *параметра шляху* визначені заздалегідь, інтерактивна документація зможе красиво їх відобразити:
<img src="/img/tutorial/path-params/image03.png">
### Робота з *перелічуваннями* у Python
Значення *параметра шляху* буде елементом *перелічування*.
#### Порівняння *елементів перелічування*
Ви можете порівнювати його з *елементами перелічування* у створеному вами enum `ModelName`:
{* ../../docs_src/path_params/tutorial005.py hl[17] *}
#### Отримання *значення перелічування*
Ви можете отримати фактичне значення (у цьому випадку це `str`), використовуючи `model_name.value`, або загалом `your_enum_member.value`:
{* ../../docs_src/path_params/tutorial005.py hl[20] *}
/// tip | Порада
Ви також можете отримати доступ до значення `"lenet"`, використовуючи `ModelName.lenet.value`.
///
#### Повернення *елементів перелічування*
Ви можете повертати *елементи перелічування* з вашої *операції шляху*, навіть вкладені у JSON-тіло (наприклад, `dict`).
Вони будуть перетворені на відповідні значення (у цьому випадку рядки) перед поверненням клієнту:
{* ../../docs_src/path_params/tutorial005.py hl[18,21,23] *}
На стороні клієнта Ви отримаєте відповідь у форматі JSON, наприклад:
```JSON
{
"model_name": "alexnet",
"message": "Deep Learning FTW!"
}
```
## Path-параметри, що містять шляхи
Припустимо, у вас є *операція шляху* з маршрутом `/files/{file_path}`.
Але вам потрібно, щоб `file_path` містив *шлях*, наприклад `home/johndoe/myfile.txt`.
Отже, URL для цього файлу виглядатиме так: `/files/home/johndoe/myfile.txt`.
### Підтримка OpenAPI
OpenAPI не підтримує спосіб оголошення *параметра шляху*, що містить *шлях* всередині, оскільки це може призвести до сценаріїв, які складно тестувати та визначати.
Однак (одначе), Ви все одно можете зробити це в **FastAPI**, використовуючи один із внутрішніх інструментів Starlette.
Документація все ще працюватиме, хоча й не додаватиме опису про те, що параметр повинен містити шлях.
### Конвертер шляху
Використовуючи опцію безпосередньо зі Starlette, Ви можете оголосити *параметр шляху*, що містить *шлях*, використовуючи URL на кшталт:
```
/files/{file_path:path}
```
У цьому випадку ім'я параметра — `file_path`, а остання частина `:path` вказує на те, що параметр повинен відповідати будь-якому *шляху*.
Отже, Ви можете використати його так:
{* ../../docs_src/path_params/tutorial004.py hl[6] *}
/// tip | Порада
Вам може знадобитися, щоб параметр містив `/home/johndoe/myfile.txt` із початковою косою рискою (`/`).
У такому випадку URL виглядатиме так: `/files//home/johndoe/myfile.txt`, із подвійною косою рискою (`//`) між `files` і `home`.
///
## Підсумок
З **FastAPI**, використовуючи короткі, інтуїтивно зрозумілі та стандартні оголошення типів Python, Ви отримуєте:
* Підтримку в редакторі: перевірка помилок, автодоповнення тощо.
* "<abbr title="перетворення рядка, що надходить з HTTP-запиту, у типи даних Python">Парсинг</abbr>" даних
* Валідацію даних
* Анотацію API та автоматичну документацію
І вам потрібно оголосити їх лише один раз.
Це, ймовірно, основна видима перевага **FastAPI** порівняно з альтернативними фреймворками (окрім високої продуктивності).

192
docs/uk/docs/tutorial/query-params.md

@ -0,0 +1,192 @@
# Query Параметри
Коли Ви оголошуєте інші параметри функції, які не є частиною параметрів шляху, вони автоматично інтерпретуються як "query" параметри.
{* ../../docs_src/query_params/tutorial001.py hl[9] *}
Query параметри — це набір пар ключ-значення, що йдуть після символу `?` в URL, розділені символами `&`.
Наприклад, в URL:
```
http://127.0.0.1:8000/items/?skip=0&limit=10
```
...query параметрами є:
* `skip`: зі значенням `0`
* `limit`: зі значенням `10`
Оскільки вони є частиною URL, вони "за замовчуванням" є рядками.
Але коли Ви оголошуєте їх із типами Python (у наведеному прикладі як `int`), вони перетворюються на цей тип і проходять перевірку відповідності.
Увесь той самий процес, який застосовується до параметрів шляху, також застосовується до query параметрів:
* Підтримка в редакторі (автодоповнення, перевірка помилок)
* <abbr title="перетворення рядка, що надходить з HTTP-запиту, у типи даних Python">"Парсинг"</abbr> даних
* Валідація даних
* Автоматична документація
## Значення за замовчуванням
Оскільки query параметри не є фіксованою частиною шляху, вони можуть бути необов’язковими та мати значення за замовчуванням.
У наведеному вище прикладі вони мають значення за замовчуванням: `skip=0` і `limit=10`.
Отже, результат переходу за URL:
```
http://127.0.0.1:8000/items/
```
буде таким самим, як і перехід за посиланням:
```
http://127.0.0.1:8000/items/?skip=0&limit=10
```
Але якщо Ви перейдете, наприклад, за посиланням:
```
http://127.0.0.1:8000/items/?skip=20
```
Значення параметрів у вашій функції будуть такими:
* `skip=20`: оскільки Ви вказали його в URL
* `limit=10`: оскільки це значення за замовчуванням
## Необов'язкові параметри
Аналогічно, Ви можете оголосити необов’язкові query параметри, встановивши для них значення за замовчуванням `None`:
{* ../../docs_src/query_params/tutorial002_py310.py hl[7] *}
У цьому випадку параметр функції `q` буде необов’язковим і за замовчуванням матиме значення `None`.
/// check | Примітка
Також зверніть увагу, що **FastAPI** достатньо розумний, щоб визначити, що параметр шляху `item_id` є параметром шляху, а `q` — ні, отже, це query параметр.
///
## Перетворення типу Query параметра
Ви також можете оголошувати параметри типу `bool`, і вони будуть автоматично конвертовані:
{* ../../docs_src/query_params/tutorial003_py310.py hl[7] *}
У цьому випадку, якщо Ви звернетесь до:
```
http://127.0.0.1:8000/items/foo?short=1
```
або
```
http://127.0.0.1:8000/items/foo?short=True
```
або
```
http://127.0.0.1:8000/items/foo?short=true
```
або
```
http://127.0.0.1:8000/items/foo?short=on
```
або
```
http://127.0.0.1:8000/items/foo?short=yes
```
або будь-який інший варіант написання (великі літери, перша літера велика тощо), ваша функція побачить параметр `short` зі значенням `True` з типом даних `bool`. В іншому випадку – `False`.
## Кілька path і query параметрів
Ви можете одночасно оголошувати кілька path і query параметрів, і **FastAPI** автоматично визначить, який з них до чого належить.
Не потрібно дотримуватись певного порядку їх оголошення.
Вони визначаються за назвою:
{* ../../docs_src/query_params/tutorial004_py310.py hl[6,8] *}
## Обов’язкові Query параметри
Якщо Ви оголошуєте значення за замовчуванням для параметрів, які не є path-параметрами (у цьому розділі ми бачили поки що лише path параметри), тоді вони стають необов’язковими.
Якщо Ви не хочете вказувати конкретні значення, але хочете зробити параметр опціональним, задайте `None` як значення за замовчуванням.
Але якщо Ви хочете зробити query параметр обов’язковим, просто не вказуйте для нього значення за замовчуванням:
{* ../../docs_src/query_params/tutorial005.py hl[6:7] *}
Тут `needy` – обов’язковий query параметр типу `str`.
Якщо Ви відкриєте у браузері URL-адресу:
```
http://127.0.0.1:8000/items/foo-item
```
...без додавання обов’язкового параметра `needy`, Ви побачите помилку:
```JSON
{
"detail": [
{
"type": "missing",
"loc": [
"query",
"needy"
],
"msg": "Field required",
"input": null,
"url": "https://errors.pydantic.dev/2.1/v/missing"
}
]
}
```
Оскільки `needy` є обов’язковим параметром, вам потрібно вказати його в URL:
```
http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
```
...цей запит поверне:
```JSON
{
"item_id": "foo-item",
"needy": "sooooneedy"
}
```
Звичайно, Ви можете визначити деякі параметри як обов’язкові, інші зі значенням за замовчуванням, а ще деякі — повністю опціональні:
{* ../../docs_src/query_params/tutorial006_py310.py hl[8] *}
У цьому випадку є 3 query параметри:
* `needy`, обов’язковий `str`.
* `skip`, `int` зі значенням за замовчуванням `0`.
* `limit`, опціональний `int`.
/// tip | Підказка
Ви також можете використовувати `Enum`-и, так само як і з [Path Parameters](path-params.md#predefined-values){.internal-link target=_blank}.
///

175
docs/uk/docs/tutorial/request-files.md

@ -0,0 +1,175 @@
# Запит файлів
Ви можете визначити файли, які будуть завантажуватися клієнтом, використовуючи `File`.
/// info | Інформація
Щоб отримувати завантажені файли, спочатку встановіть <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">python-multipart</a>.
Переконайтеся, що Ви створили [віртуальне середовище](../virtual-environments.md){.internal-link target=_blank}, активували його та встановили пакет, наприклад:
```console
$ pip install python-multipart
```
Це необхідно, оскільки завантажені файли передаються у вигляді "форматованих даних форми".
///
## Імпорт `File`
Імпортуйте `File` та `UploadFile` з `fastapi`:
{* ../../docs_src/request_files/tutorial001_an_py39.py hl[3] *}
## Визначення параметрів `File`
Створіть параметри файлів так само як Ви б створювали `Body` або `Form`:
{* ../../docs_src/request_files/tutorial001_an_py39.py hl[9] *}
/// info | Інформація
`File` — це клас, який безпосередньо успадковує `Form`.
Але пам’ятайте, що коли Ви імпортуєте `Query`, `Path`, `File` та інші з `fastapi`, це насправді функції, які повертають спеціальні класи.
///
/// tip | Підказка
Щоб оголосити тіла файлів, Вам потрібно використовувати `File`, тому що інакше параметри будуть інтерпретовані як параметри запиту або параметри тіла (JSON).
///
Файли будуть завантажені у вигляді "форматованих даних форми".
Якщо Ви оголосите тип параметра функції обробника маршруту як `bytes`, **FastAPI** прочитає файл за Вас, і Ви отримаєте його вміст у вигляді `bytes`.
Однак майте на увазі, що весь вміст буде збережено в пам'яті. Це працюватиме добре для малих файлів.
Але в деяких випадках Вам може знадобитися `UploadFile`.
## Параметри файлу з `UploadFile`
Визначте параметр файлу з типом `UploadFile`:
{* ../../docs_src/request_files/tutorial001_an_py39.py hl[14] *}
Використання `UploadFile` має кілька переваг перед `bytes`:
* Вам не потрібно використовувати `File()` у значенні за замовчуванням параметра.
* Використовується "буферизований" файл:
* Файл зберігається в пам'яті до досягнення певного обмеження, після чого він записується на диск.
* Це означає, що він добре працює для великих файлів, таких як зображення, відео, великі двійкові файли тощо, не споживаючи всю пам'ять.
Ви можете отримати метадані про завантажений файл.
* Він має <a href="https://docs.python.org/3/glossary.html#term-file-like-object" class="external-link" target="_blank">file-like</a> `асинхронний файловий інтерфейс` interface.
* Він надає фактичний об'єкт Python <a href="https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile" class="external-link" target="_blank">`SpooledTemporaryFile`</a>, який можна передавати безпосередньо іншим бібліотекам.
### `UploadFile`
`UploadFile` має такі атрибути:
* `filename`: Рядок `str` з оригінальною назвою файлу, який був завантажений (наприклад, `myimage.jpg`).
* `content_type`: Рядок `str` з MIME-типом (наприклад, `image/jpeg`).
* `file`: Об'єкт <a href="https://docs.python.org/3/library/tempfile.html#tempfile.SpooledTemporaryFile" class="external-link" target="_blank">SpooledTemporaryFile</a> (<a href="https://docs.python.org/3/glossary.html#term-file-like-object" class="external-link" target="_blank">файлоподібний</a> об'єкт). Це фактичний файловий об'єкт Python, який можна безпосередньо передавати іншим функціям або бібліотекам, що очікують "файлоподібний" об'єкт.
`UploadFile` має такі асинхронні `async` методи. Вони викликають відповідні методи файлу під капотом (використовуючи внутрішній `SpooledTemporaryFile`).
* `write(data)`: Записує `data` (`str` або `bytes`) у файл.
* `read(size)`: Читає `size` (`int`) байтів/символів з файлу.
* `seek(offset)`: Переміщується до позиції `offset` (`int`) у файлі.
* Наприклад, `await myfile.seek(0)` поверне курсор на початок файлу.
* This is especially useful if you run `await myfile.read()` once and then need to read the contents again. Це особливо корисно, якщо Ви виконуєте await `await myfile.read()` один раз, а потім потрібно знову прочитати вміст.
* `close()`: Закриває файл.
Оскільки всі ці методи є асинхронними `async`, Вам потрібно використовувати "await":
Наприклад, всередині `async` *функції обробки шляху* Ви можете отримати вміст за допомогою:
```Python
contents = await myfile.read()
```
Якщо Ви знаходитесь у звичайній `def` *функції обробки шляху*, Ви можете отримати доступ до `UploadFile.file` безпосередньо, наприклад:
```Python
contents = myfile.file.read()
```
/// note | Технічні деталі `async`
Коли Ви використовуєте `async` методи, **FastAPI** виконує файлові операції у пулі потоків та очікує їх завершення.
///
/// note | Технічні деталі Starlette
`UploadFile` у **FastAPI** успадковується безпосередньо від `UploadFile` у **Starlette**, але додає деякі необхідні частини, щоб зробити його сумісним із **Pydantic** та іншими компонентами FastAPI.
///
## Що таке "Form Data"
Спосіб, у який HTML-форми (`<form></form>`) надсилають дані на сервер, зазвичай використовує "спеціальне" кодування, відмінне від JSON.
**FastAPI** забезпечує правильне зчитування цих даних з відповідної частини запиту, а не з JSON.
/// note | Технічні деталі
Дані з форм зазвичай кодуються за допомогою "media type" `application/x-www-form-urlencoded`, якщо вони не містять файлів.
Але якщо форма містить файли, вона кодується у форматі `multipart/form-data`. Якщо Ви використовуєте `File`, **FastAPI** визначить, що потрібно отримати файли з відповідної частини тіла запиту.
Щоб дізнатися більше про ці типи кодування та формові поля, ознайомтеся з <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network">документацією MDN</abbr> щодо <code>POST</code></a>.
///
/// warning | Увага
Ви можете оголосити кілька параметрів `File` і `Form` в *операції шляху*, але Ви не можете одночасно оголошувати поля `Body`, які мають надходити у форматі JSON, оскільки тіло запиту буде закодоване у форматі `multipart/form-data`, а не `application/json`.
Це не обмеження **FastAPI**, а особливість протоколу HTTP.
///
## Опціональне Завантаження Файлів
Файл можна зробити необов’язковим, використовуючи стандартні анотації типів і встановлюючи значення за замовчуванням `None`:
{* ../../docs_src/request_files/tutorial001_02_an_py310.py hl[9,17] *}
## `UploadFile` із Додатковими Мета Даними
Ви також можете використовувати `File()` разом із `UploadFile`, наприклад, для встановлення додаткових метаданих:
{* ../../docs_src/request_files/tutorial001_03_an_py39.py hl[9,15] *}
## Завантаження Кількох Файлів
Можна завантажувати кілька файлів одночасно.
Вони будуть пов’язані з одним і тим самим "form field", який передається у вигляді "form data".
Щоб це реалізувати, потрібно оголосити список `bytes` або `UploadFile`:
{* ../../docs_src/request_files/tutorial002_an_py39.py hl[10,15] *}
Ви отримаєте, як і було оголошено, `list` із `bytes` або `UploadFile`.
/// note | Технічні деталі
Ви також можете використати `from starlette.responses import HTMLResponse`.
**FastAPI** надає ті ж самі `starlette.responses`, що й `fastapi.responses`, для зручності розробників. Однак більшість доступних відповідей надходять безпосередньо від Starlette.
///
### Завантаження декількох файлів із додатковими метаданими
Так само як і раніше, Ви можете використовувати `File()`, щоб встановити додаткові параметри навіть для `UploadFile`:
{* ../../docs_src/request_files/tutorial003_an_py39.py hl[11,18:20] *}
## Підсумок
Використовуйте `File`, `bytes`та `UploadFile`, щоб оголошувати файли для завантаження у запитах, які надсилаються у вигляді form data.

78
docs/uk/docs/tutorial/request-form-models.md

@ -0,0 +1,78 @@
# Моделі форм (Form Models)
У FastAPI Ви можете використовувати **Pydantic-моделі** для оголошення **полів форми**.
/// info | Інформація
Щоб використовувати форми, спочатку встановіть <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">python-multipart</a>.
Переконайтеся, що Ви створили [віртуальне середовище](../virtual-environments.md){.internal-link target=_blank}, активували його, а потім встановили бібліотеку, наприклад:
```console
$ pip install python-multipart
```
///
/// note | Підказка
Ця функція підтримується, починаючи з FastAPI версії `0.113.0`. 🤓
///
## Використання Pydantic-моделей для форм
Вам просто потрібно оголосити **Pydantic-модель** з полями, які Ви хочете отримати як **поля форми**, а потім оголосити параметр як `Form`:
{* ../../docs_src/request_form_models/tutorial001_an_py39.py hl[9:11,15] *}
**FastAPI** **витягне** дані для **кожного поля** з **формових даних** у запиті та надасть вам Pydantic-модель, яку Ви визначили.
## Перевірка документації
Ви можете перевірити це в UI документації за `/docs`:
<div class="screenshot">
<img src="/img/tutorial/request-form-models/image01.png">
</div>
## Заборона додаткових полів форми
У деяких особливих випадках (ймовірно, рідко) Ви можете **обмежити** форму лише тими полями, які були оголошені в Pydantic-моделі, і **заборонити** будь-які **додаткові** поля.
/// note | Підказка
Ця функція підтримується, починаючи з FastAPI версії `0.114.0`. 🤓
///
Ви можете використати конфігурацію Pydantic-моделі, щоб заборонити `forbid` будь-які додаткові `extra` поля:
{* ../../docs_src/request_form_models/tutorial002_an_py39.py hl[12] *}
Якщо клієнт спробує надіслати додаткові дані, він отримає **відповідь з помилкою**.
Наприклад, якщо клієнт спробує надіслати наступні поля форми:
* `username`: `Rick`
* `password`: `Portal Gun`
* `extra`: `Mr. Poopybutthole`
Він отримає відповідь із помилкою, яка повідомляє, що поле `extra` не дозволено:
```json
{
"detail": [
{
"type": "extra_forbidden",
"loc": ["body", "extra"],
"msg": "Extra inputs are not permitted",
"input": "Mr. Poopybutthole"
}
]
}
```
## Підсумок
Ви можете використовувати Pydantic-моделі для оголошення полів форми у FastAPI. 😎

41
docs/uk/docs/tutorial/request-forms-and-files.md

@ -0,0 +1,41 @@
# Запити з формами та файлами
У FastAPI Ви можете одночасно отримувати файли та поля форми, використовуючи `File` і `Form`.
/// info | Інформація
Щоб отримувати завантажені файли та/або дані форми, спочатку встановіть <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">python-multipart</a>.
Переконайтеся, що Ви створили [віртуальне середовище](../virtual-environments.md){.internal-link target=_blank}, активували його, а потім встановили бібліотеку, наприклад:
```console
$ pip install python-multipart
```
///
## Імпорт `File` та `Form`
{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[3] *}
## Оголошення параметрів `File` та `Form`
Створіть параметри файлів та форми так само як і для `Body` або `Query`:
{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[10:12] *}
Файли та поля форми будуть завантажені як формові дані, і Ви отримаєте як файли, так і введені користувачем поля.
Ви також можете оголосити деякі файли як `bytes`, а деякі як `UploadFile`.
/// warning | Увага
Ви можете оголосити кілька параметрів `File` і `Form` в операції *шляху*, але не можете одночасно оголошувати `Body`-поля, які очікуєте отримати у форматі JSON, оскільки запит матиме тіло, закодоване за допомогою `multipart/form-data`, а не `application/json`.
Це не обмеження **FastAPI**, а частина протоколу HTTP.
///
## Підсумок
Використовуйте `File` та `Form` разом, коли вам потрібно отримувати дані форми та файли в одному запиті.

73
docs/uk/docs/tutorial/request-forms.md

@ -0,0 +1,73 @@
# Дані форми
Якщо Вам потрібно отримувати поля форми замість JSON, Ви можете використовувати `Form`.
/// info | Інформація
Щоб використовувати форми, спочатку встановіть <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>.
Переконайтеся, що Ви створили [віртуальне середовище](../virtual-environments.md){.internal-link target=_blank}, активували його, і потім встановили бібліотеку, наприклад:
```console
$ pip install python-multipart
```
///
## Імпорт `Form`
Імпортуйте `Form` з `fastapi`:
{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[3] *}
## Оголошення параметрів `Form`
Створюйте параметри форми так само як Ви б створювали `Body` або `Query`:
{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[9] *}
Наприклад, один зі способів використання специфікації OAuth2 (так званий "password flow") вимагає надсилати `username` та `password` як поля форми.
<abbr title="Специфікація">spec</abbr> вимагає, щоб ці поля мали точні назви `username` і `password` та надсилалися у вигляді полів форми, а не JSON.
З `Form` Ви можете оголошувати ті ж конфігурації, що і з `Body` (та `Query`, `Path`, `Cookie`), включаючи валідацію, приклади, псевдоніми (наприклад, `user-name` замість `username`) тощо.
/// info | Інформація
`Form` — це клас, який безпосередньо наслідується від `Body`.
///
/// tip | Порада
Щоб оголосити тіло форми, потрібно явно використовувати `Form`, оскільки без нього параметри будуть інтерпретуватися як параметри запиту або тіла (JSON).
///
## Про "поля форми"
HTML-форми (`<form></form>`) надсилають дані на сервер у "спеціальному" кодуванні, яке відрізняється від JSON.
**FastAPI** подбає про те, щоб зчитати ці дані з правильного місця, а не з JSON.
/// note | Технічні деталі
Дані з форм зазвичай кодуються за допомогою "типу медіа" `application/x-www-form-urlencoded`.
Але якщо форма містить файли, вона кодується як `multipart/form-data`. Ви дізнаєтеся про обробку файлів у наступному розділі.
Якщо Ви хочете дізнатися більше про ці кодування та поля форм, зверніться до <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST" class="external-link" target="_blank"><abbr title="Mozilla Developer Network">MDN</abbr> вебдокументації для <code>POST</code></a>.
///
/// warning | Попередження
Ви можете оголосити кілька параметрів `Form` в *операції шляху*, але не можете одночасно оголосити поля `Body`, які Ви очікуєте отримати у форматі JSON, оскільки тіло запиту буде закодовано у форматі `application/x-www-form-urlencoded`, а не `application/json`.
Це не обмеження **FastAPI**, а частина HTTP-протоколу.
///
## Підсумок
Використовуйте `Form` для оголошення вхідних параметрів у вигляді даних форми.

240
docs/uk/docs/tutorial/testing.md

@ -0,0 +1,240 @@
# Тестування
Тестування **FastAPI** додатків є простим та ефективним завдяки бібліотеці <a href="https://www.starlette.io/testclient/" class="external-link" target="_blank">Starlette</a>, яка базується на <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a>.
Оскільки HTTPX розроблений на основі Requests, його API є інтуїтивно зрозумілим для тих, хто вже знайомий з Requests.
З його допомогою Ви можете використовувати <a href="https://docs.pytest.org/" class="external-link" target="_blank">pytest</a> безпосередньо з **FastAPI**.
## Використання `TestClient`
/// info | Інформація
Щоб використовувати `TestClient`, спочатку встановіть <a href="https://www.python-httpx.org" class="external-link" target="_blank">`httpx`</a>.
Переконайтеся, що Ви створили [віртуальне середовище](../virtual-environments.md){.internal-link target=_blank}, активували його, а потім встановили саму бібліотеку, наприклад:
```console
$ pip install httpx
```
///
Імпортуйте `TestClient`.
Створіть `TestClient`, передавши йому Ваш застосунок **FastAPI**.
Створюйте функції з іменами, що починаються з `test_` (це стандартна угода для `pytest`).
Використовуйте об'єкт `TestClient` так само як і `httpx`.
Записуйте прості `assert`-вирази зі стандартними виразами Python, які потрібно перевірити (це також стандарт для `pytest`).
{* ../../docs_src/app_testing/tutorial001.py hl[2,12,15:18] *}
/// tip | Порада
Зверніть увагу, що тестові функції — це звичайні `def`, а не `async def`.
Виклики клієнта також звичайні, без використання `await`.
Це дозволяє використовувати `pytest` без зайвих ускладнень.
///
/// note | Технічні деталі
Ви також можете використовувати `from starlette.testclient import TestClient`.
**FastAPI** надає той самий `starlette.testclient` під назвою `fastapi.testclient` для зручності розробників, але він безпосередньо походить із Starlette.
///
/// tip | Порада
Якщо Вам потрібно викликати `async`-функції у ваших тестах, окрім відправлення запитів до FastAPI-застосунку (наприклад, асинхронні функції роботи з базою даних), перегляньте [Асинхронні тести](../advanced/async-tests.md){.internal-link target=_blank} у розширеному керівництві.
///
## Розділення тестів
У реальному застосунку Ваші тести, ймовірно, будуть в окремому файлі.
Також Ваш **FastAPI**-застосунок може складатися з кількох файлів або модулів тощо.
### Файл застосунку **FastAPI**
Припустимо, у Вас є структура файлів, описана в розділі [Більші застосунки](bigger-applications.md){.internal-link target=_blank}:
```
.
├── app
│   ├── __init__.py
│   └── main.py
```
У файлі `main.py` знаходиться Ваш застосунок **FastAPI** :
{* ../../docs_src/app_testing/main.py *}
### Файл тестування
Ви можете створити файл `test_main.py` з Вашими тестами. Він може знаходитися в тому ж пакеті Python (у тій самій директорії з файлом `__init__.py`):
``` hl_lines="5"
.
├── app
│   ├── __init__.py
│   ├── main.py
│   └── test_main.py
```
Оскільки цей файл знаходиться в тому ж пакеті, Ви можете використовувати відносний імпорт, щоб імпортувати об'єкт `app` із модуля `main` (`main.py`):
{* ../../docs_src/app_testing/test_main.py hl[3] *}
...і написати код для тестів так само як і раніше.
## Тестування: розширений приклад
Тепер розширимо цей приклад і додамо більше деталей, щоб побачити, як тестувати різні частини.
### Розширений файл застосунку **FastAPI**
Залишимо ту саму структуру файлів:
```
.
├── app
│   ├── __init__.py
│   ├── main.py
│   └── test_main.py
```
Припустимо, що тепер файл `main.py` із Вашим **FastAPI**-застосунком містить додаткові операції шляху (**path operations**).
Він має `GET`-операцію, яка може повертати помилку.
Він має `POST`-операцію, яка може повертати кілька помилок.
Обидві операції шляху вимагають заголовок `X-Token`.
//// tab | Python 3.10+
```Python
{!> ../../docs_src/app_testing/app_b_an_py310/main.py!}
```
////
//// tab | Python 3.9+
```Python
{!> ../../docs_src/app_testing/app_b_an_py39/main.py!}
```
////
//// tab | Python 3.8+
```Python
{!> ../../docs_src/app_testing/app_b_an/main.py!}
```
////
//// tab | Python 3.10+ non-Annotated
/// tip | Порада
Бажано використовувати версію з `Annotated`, якщо це можливо
///
```Python
{!> ../../docs_src/app_testing/app_b_py310/main.py!}
```
////
//// tab | Python 3.8+ non-Annotated
/// tip | Порада
Бажано використовувати версію з `Annotated`, якщо це можливо
///
```Python
{!> ../../docs_src/app_testing/app_b/main.py!}
```
////
### Розширений тестовий файл
Потім Ви можете оновити `test_main.py`, додавши розширені тести:
{* ../../docs_src/app_testing/app_b/test_main.py *}
Коли Вам потрібно передати клієнту інформацію в запиті, але Ви не знаєте, як це зробити, Ви можете пошукати (наприклад, у Google) спосіб реалізації в `httpx`, або навіть у `requests`, оскільки HTTPX розроблений на основі дизайну Requests.
Далі Ви просто повторюєте ці ж дії у ваших тестах.
Наприклад:
* Щоб передати *path* або *query* параметр, додайте його безпосередньо до URL.
* Щоб передати тіло JSON, передайте Python-об'єкт (наприклад, `dict`) у параметр `json`.
* Якщо потрібно надіслати *Form Data* замість JSON, використовуйте параметр `data`.
* Щоб передати заголовки *headers*, використовуйте `dict` у параметрі `headers`.
* Для *cookies* використовуйте `dict` у параметрі `cookies`.
Докладніше про передачу даних у бекенд (за допомогою `httpx` або `TestClient`) можна знайти в <a href="https://www.python-httpx.org" class="external-link" target="_blank">документації HTTPX</a>.
/// info | Інформація
Зверніть увагу, що `TestClient` отримує дані, які можна конвертувати в JSON, а не Pydantic-моделі.
Якщо у Вас є Pydantic-модель у тесті, і Ви хочете передати її дані в додаток під час тестування, Ви можете використати `jsonable_encoder`, описаний у розділі [JSON Compatible Encoder](encoder.md){.internal-link target=_blank}.
///
## Запуск тестів
Після цього вам потрібно встановити `pytest`.
Переконайтеся, що Ви створили [віртуальне середовище]{.internal-link target=_blank}, активували його і встановили необхідні пакети, наприклад:
<div class="termy">
```console
$ pip install pytest
---> 100%
```
</div>
`pytest` автоматично знайде файли з тестами, виконає їх і надасть вам результати.
Запустіть тести за допомогою:
<div class="termy">
```console
$ pytest
================ test session starts ================
platform linux -- Python 3.6.9, pytest-5.3.5, py-1.8.1, pluggy-0.13.1
rootdir: /home/user/code/superawesome-cli/app
plugins: forked-1.1.3, xdist-1.31.0, cov-2.8.1
collected 6 items
---> 100%
test_main.py <span style="color: green; white-space: pre;">...... [100%]</span>
<span style="color: green;">================= 1 passed in 0.03s =================</span>
```
</div>

17
docs/vi/docs/deployment/cloud.md

@ -0,0 +1,17 @@
# Triển khai FastAPI trên các Dịch vụ Cloud
Bạn có thể sử dụng **bất kỳ nhà cung cấp dịch vụ cloud** nào để triển khai ứng dụng FastAPI của mình.
Trong hầu hết các trường hợp, các nhà cung cấp dịch vụ cloud lớn đều có hướng dẫn triển khai FastAPI với họ.
## Nhà cung cấp dịch vụ Cloud - Nhà tài trợ
Một vài nhà cung cấp dịch vụ cloud ✨ [**tài trợ cho FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, điều này giúp đảm bảo sự phát triển liên tục và khỏe mạnh của FastAPI và hệ sinh thái của nó.
Thêm nữa, điều này cũng thể hiện cam kết thực sự của họ đối với FastAPI và **cộng đồng người dùng** (bạn), vì họ không chỉ muốn cung cấp cho bạn một **dịch vụ tốt** mà còn muốn đảm bảo rằng bạn có một **framework tốt và bền vững**, đó chính là FastAPI. 🙇
Bạn có thể thử các dịch vụ của họ và làm theo hướng dẫn của họ:
* <a href="https://docs.platform.sh/languages/python.html?utm_source=fastapi-signup&utm_medium=banner&utm_campaign=FastAPI-signup-June-2023" class="external-link" target="_blank">Platform.sh</a>
* <a href="https://docs.porter.run/language-specific-guides/fastapi" class="external-link" target="_blank">Porter</a>
* <a href="https://www.withcoherence.com/?utm_medium=advertising&utm_source=fastapi&utm_campaign=website" class="external-link" target="_blank">Coherence</a>
* <a href="https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi" class="external-link" target="_blank">Render</a>

21
docs/vi/docs/deployment/index.md

@ -0,0 +1,21 @@
# Triển khai
Triển khai một ứng dụng **FastAPI** khá dễ dàng.
## Triển khai là gì
Triển khai một ứng dụng có nghĩa là thực hiện các bước cần thiết để làm cho nó **sẵn sàng phục vụ người dùng**.
Đối với một **API web**, điều này có nghĩa là đặt nó trong một **máy chủ từ xa**, với một **chương trình máy chủ** cung cấp hiệu suất tốt, ổn định, v.v., để người dùng của bạn có thể truy cập ứng dụng của bạn một cách hiệu quả và không bị gián đoạn hoặc gặp vấn đề.
Điều này trái ngược với các **giai đoạn phát triển**, trong đó bạn liên tục thay đổi mã, phá vỡ nó và sửa nó, ngừng và khởi động lại máy chủ phát triển, v.v.
## Các Chiến lược Triển khai
Có nhiều cách để triển khai ứng dụng của bạn tùy thuộc vào trường hợp sử dụng của bạn và các công cụ mà bạn sử dụng.
Bạn có thể **triển khai một máy chủ** của riêng bạn bằng cách sử dụng một sự kết hợp các công cụ, hoặc bạn có thể sử dụng một **dịch vụ cloud** để làm một số công việc cho bạn, hoặc các tùy chọn khác.
Tôi sẽ chỉ ra một số khái niệm chính cần thiết khi triển khai một ứng dụng **FastAPI** (mặc dù hầu hết nó áp dụng cho bất kỳ loại ứng dụng web nào).
Bạn sẽ thấy nhiều chi tiết cần thiết và một số kỹ thuật để triển khai trong các phần tiếp theo. ✨

93
docs/vi/docs/deployment/versions.md

@ -0,0 +1,93 @@
# Về các phiên bản của FastAPI
**FastAPI** đã được sử dụng ở quy mô thực tế (production) trong nhiều ứng dụng và hệ thống. Và phạm vi kiểm thử được giữ ở mức 100%. Nhưng việc phát triển của nó vẫn đang diễn ra nhanh chóng.
Các tính năng mới được bổ sung thường xuyên, lỗi được sửa định kỳ, và mã nguồn vẫn đang được cải thiện liên tục
Đó là lí do các phiên bản hiện tại vẫn còn là 0.x.x, điều này phản ánh rằng mỗi phiên bản có thể có các thay đổi gây mất tương thích. Điều này tuân theo các quy ước về <a href="https://semver.org/" class="external-link" target="blank">Semantic Versioning</a>.
Bạn có thể tạo ra sản phẩm thực tế với **FastAPI** ngay bây giờ (và bạn có thể đã làm điều này trong một thời gian dài), bạn chỉ cần đảm bảo rằng bạn sử dụng một phiên bản hoạt động đúng với các đoạn mã còn lại của bạn.
## Cố định phiên bản của `fastapi`
Điều đầu tiên bạn nên làm là "cố định" phiên bản của **FastAPI** bạn đang sử dụng để phiên bản mới nhất mà bạn biết hoạt động đúng với ứng dụng của bạn.
Ví dụ, giả sử bạn đang sử dụng phiên bản `0.112.0` trong ứng dụng của bạn.
Nếu bạn sử dụng một tệp `requirements.txt` bạn có thể chỉ định phiên bản với:
```txt
fastapi[standard]==0.112.0
```
Như vậy, bạn sẽ sử dụng chính xác phiên bản `0.112.0`.
Hoặc bạn cũng có thể cố định nó với:
```txt
fastapi[standard]>=0.112.0,<0.113.0
```
Như vậy, bạn sẽ sử dụng các phiên bản `0.112.0` trở lên, nhưng nhỏ hơn `0.113.0`, ví dụ, một phiên bản `0.112.2` vẫn được chấp nhận.
Nếu bạn sử dụng bất kỳ công cụ nào để quản lý cài đặt của bạn, như `uv`, Poetry, Pipenv, hoặc bất kỳ công cụ nào khác, chúng đều có một cách để bạn có thể định nghĩa các phiên bản cụ thể cho các gói của bạn.
## Các phiên bản có sẵn
Bạn có thể xem các phiên bản có sẵn (ví dụ để kiểm tra phiên bản mới nhất) trong [Release Notes](../release-notes.md){.internal-link target=_blank}.
## Về các phiên bản
Theo quy ước về Semantic Versioning, bất kỳ phiên bản nào bên dưới `1.0.0` có thể thêm các thay đổi gây mất tương thích.
**FastAPI** cũng theo quy ước rằng bất kỳ thay đổi phiên bản "PATCH" nào là cho các lỗi và các thay đổi không gây mất tương thích.
/// tip
"PATCH" là số cuối cùng, ví dụ, trong `0.2.3`, phiên bản PATCH là `3`.
///
Vì vậy, bạn có thể cố định đến một phiên bản như:
```txt
fastapi>=0.45.0,<0.46.0
```
Các thay đổi gây mất tương thích và các tính năng mới được thêm vào trong các phiên bản "MINOR".
/// tip
"MINOR" là số ở giữa, ví dụ, trong `0.2.3`, phiên bản MINOR là `2`.
///
## Nâng cấp các phiên bản của FastAPI
Bạn nên thêm các bài kiểm tra (tests) cho ứng dụng của bạn.
Với **FastAPI** điều này rất dễ dàng (nhờ vào Starlette), kiểm tra tài liệu: [Testing](../tutorial/testing.md){.internal-link target=_blank}
Sau khi bạn có các bài kiểm tra, bạn có thể nâng cấp phiên bản **FastAPI** lên một phiên bản mới hơn, và đảm bảo rằng tất cả mã của bạn hoạt động đúng bằng cách chạy các bài kiểm tra của bạn.
Nếu mọi thứ đang hoạt động, hoặc sau khi bạn thực hiện các thay đổi cần thiết, và tất cả các bài kiểm tra của bạn đều đi qua, thì bạn có thể cố định phiên bản của `fastapi` đến phiên bản mới hơn.
## Về Starlette
Bạn không nên cố định phiên bản của `starlette`.
Các phiên bản khác nhau của **FastAPI** sẽ sử dụng một phiên bản Starlette mới hơn.
Vì vậy, bạn có thể để **FastAPI** sử dụng phiên bản Starlette phù hợp.
## Về Pydantic
Pydantic bao gồm các bài kiểm tra của riêng nó cho **FastAPI**, vì vậy các phiên bản mới hơn của Pydantic (trên `1.0.0`) luôn tương thích với **FastAPI**.
Bạn có thể cố định Pydantic đến bất kỳ phiên bản nào trên `1.0.0` mà bạn muốn.
Ví dụ:
```txt
pydantic>=2.7.0,<3.0.0
```

2
docs/vi/docs/index.md

@ -12,7 +12,7 @@
</p>
<p align="center">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">

40
docs/vi/docs/tutorial/static-files.md

@ -0,0 +1,40 @@
# Tệp tĩnh (Static Files)
Bạn có thể triển khai tệp tĩnh tự động từ một thư mục bằng cách sử dụng StaticFiles.
## Sử dụng `Tệp tĩnh`
- Nhập `StaticFiles`.
- "Mount" a `StaticFiles()` instance in a specific path.
{* ../../docs_src/static_files/tutorial001.py hl[2,6] *}
/// note | Chi tiết kỹ thuật
Bạn cũng có thể sử dụng `from starlette.staticfiles import StaticFiles`.
**FastAPI** cung cấp cùng `starlette.staticfiles` như `fastapi.staticfiles` giúp đơn giản hóa việc sử dụng, nhưng nó thực sự đến từ Starlette.
///
### "Mounting" là gì
"Mounting" có nghĩa là thêm một ứng dụng "độc lập" hoàn chỉnh vào một đường dẫn cụ thể, sau đó ứng dụng đó sẽ chịu trách nhiệm xử lý tất cả các đường dẫn con.
Điều này khác với việc sử dụng `APIRouter` vì một ứng dụng được gắn kết là hoàn toàn độc lập. OpenAPI và tài liệu từ ứng dụng chính của bạn sẽ không bao gồm bất kỳ thứ gì từ ứng dụng được gắn kết, v.v.
Bạn có thể đọc thêm về điều này trong [Hướng dẫn Người dùng Nâng cao](../advanced/index.md){.internal-link target=\_blank}.
## Chi tiết
Đường dẫn đầu tiên `"/static"` là đường dẫn con mà "ứng dụng con" này sẽ được "gắn" vào. Vì vậy, bất kỳ đường dẫn nào bắt đầu bằng `"/static"` sẽ được xử lý bởi nó.
Đường dẫn `directory="static"` là tên của thư mục chứa tệp tĩnh của bạn.
Tham số `name="static"` đặt tên cho nó để có thể được sử dụng bên trong **FastAPI**.
Tất cả các tham số này có thể khác với `static`, điều chỉnh chúng với phù hợp với ứng dụng của bạn.
## Thông tin thêm
Để biết thêm chi tiết và tùy chọn, hãy xem <a href="https://www.starlette.io/staticfiles/" class="external-link" target="_blank">Starlette's docs about Static Files</a>.

2
docs/yo/docs/index.md

@ -12,7 +12,7 @@
</p>
<p align="center">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">

2
docs/zh-hant/docs/index.md

@ -6,7 +6,7 @@
</p>
<p align="center">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">

8
docs/zh/docs/index.md

@ -11,11 +11,11 @@
<em>FastAPI 框架,高性能,易于学习,高效编码,生产可用</em>
</p>
<p align="center">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest" target="_blank">
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg" alt="Test">
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://codecov.io/gh/fastapi/fastapi" target="_blank">
<img src="https://img.shields.io/codecov/c/github/fastapi/fastapi?color=%2334D058" alt="Coverage">
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">
</a>
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Package version">

27
docs/zh/docs/tutorial/query-params-str-validations.md

@ -108,21 +108,6 @@ q: Union[str, None] = Query(default=None, min_length=3)
{* ../../docs_src/query_params_str_validations/tutorial006.py hl[7] *}
### 使用省略号(`...`)声明必需参数
有另一种方法可以显式的声明一个值是必需的,即将默认参数的默认值设为 `...`
{* ../../docs_src/query_params_str_validations/tutorial006b.py hl[7] *}
/// info
如果你之前没见过 `...` 这种用法:它是一个特殊的单独值,它是 <a href="https://docs.python.org/zh-cn/3/library/constants.html#Ellipsis" class="external-link" target="_blank">Python 的一部分并且被称为“Ellipsis”(意为省略号 —— 译者注)</a>
Pydantic 和 FastAPI 使用它来显式的声明需要一个值。
///
这将使 **FastAPI** 知道此查询参数是必需的。
### 使用`None`声明必需参数
你可以声明一个参数可以接收`None`值,但它仍然是必需的。这将强制客户端发送一个值,即使该值是`None`。
@ -137,18 +122,6 @@ Pydantic 是 FastAPI 中所有数据验证和序列化的核心,当你在没
///
### 使用Pydantic中的`Required`代替省略号(`...`)
如果你觉得使用 `...` 不舒服,你也可以从 Pydantic 导入并使用 `Required`
{* ../../docs_src/query_params_str_validations/tutorial006d.py hl[2,8] *}
/// tip
请记住,在大多数情况下,当你需要某些东西时,可以简单地省略 `default` 参数,因此你通常不必使用 `...``Required`
///
## 查询参数列表 / 多个值
当你使用 `Query` 显式地定义查询参数时,你还可以声明它去接收一组值,或换句话来说,接收多个值。

2
docs_src/configure_swagger_ui/tutorial002.py

@ -1,6 +1,6 @@
from fastapi import FastAPI
app = FastAPI(swagger_ui_parameters={"syntaxHighlight.theme": "obsidian"})
app = FastAPI(swagger_ui_parameters={"syntaxHighlight": {"theme": "obsidian"}})
@app.get("/users/{username}")

11
docs_src/query_params_str_validations/tutorial006b.py

@ -1,11 +0,0 @@
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: str = Query(default=..., min_length=3)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results

12
docs_src/query_params_str_validations/tutorial006b_an.py

@ -1,12 +0,0 @@
from fastapi import FastAPI, Query
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[str, Query(min_length=3)] = ...):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results

13
docs_src/query_params_str_validations/tutorial006b_an_py39.py

@ -1,13 +0,0 @@
from typing import Annotated
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[str, Query(min_length=3)] = ...):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results

2
docs_src/query_params_str_validations/tutorial006c.py

@ -6,7 +6,7 @@ app = FastAPI()
@app.get("/items/")
async def read_items(q: Union[str, None] = Query(default=..., min_length=3)):
async def read_items(q: Union[str, None] = Query(min_length=3)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})

2
docs_src/query_params_str_validations/tutorial006c_an.py

@ -7,7 +7,7 @@ app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[Union[str, None], Query(min_length=3)] = ...):
async def read_items(q: Annotated[Union[str, None], Query(min_length=3)]):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})

2
docs_src/query_params_str_validations/tutorial006c_an_py310.py

@ -6,7 +6,7 @@ app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[str | None, Query(min_length=3)] = ...):
async def read_items(q: Annotated[str | None, Query(min_length=3)]):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})

2
docs_src/query_params_str_validations/tutorial006c_an_py39.py

@ -6,7 +6,7 @@ app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[Union[str, None], Query(min_length=3)] = ...):
async def read_items(q: Annotated[Union[str, None], Query(min_length=3)]):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})

2
docs_src/query_params_str_validations/tutorial006c_py310.py

@ -4,7 +4,7 @@ app = FastAPI()
@app.get("/items/")
async def read_items(q: str | None = Query(default=..., min_length=3)):
async def read_items(q: str | None = Query(min_length=3)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})

11
docs_src/query_params_str_validations/tutorial006d.py

@ -1,11 +0,0 @@
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: str = Query(default=..., min_length=3)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results

12
docs_src/query_params_str_validations/tutorial006d_an.py

@ -1,12 +0,0 @@
from fastapi import FastAPI, Query
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[str, Query(min_length=3)] = ...):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results

13
docs_src/query_params_str_validations/tutorial006d_an_py39.py

@ -1,13 +0,0 @@
from typing import Annotated
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Annotated[str, Query(min_length=3)] = ...):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results

31
docs_src/query_params_str_validations/tutorial015_an.py

@ -0,0 +1,31 @@
import random
from typing import Union
from fastapi import FastAPI
from pydantic import AfterValidator
from typing_extensions import Annotated
app = FastAPI()
data = {
"isbn-9781529046137": "The Hitchhiker's Guide to the Galaxy",
"imdb-tt0371724": "The Hitchhiker's Guide to the Galaxy",
"isbn-9781439512982": "Isaac Asimov: The Complete Stories, Vol. 2",
}
def check_valid_id(id: str):
if not id.startswith(("isbn-", "imdb-")):
raise ValueError('Invalid ID format, it must start with "isbn-" or "imdb-"')
return id
@app.get("/items/")
async def read_items(
id: Annotated[Union[str, None], AfterValidator(check_valid_id)] = None,
):
if id:
item = data.get(id)
else:
id, item = random.choice(list(data.items()))
return {"id": id, "name": item}

30
docs_src/query_params_str_validations/tutorial015_an_py310.py

@ -0,0 +1,30 @@
import random
from typing import Annotated
from fastapi import FastAPI
from pydantic import AfterValidator
app = FastAPI()
data = {
"isbn-9781529046137": "The Hitchhiker's Guide to the Galaxy",
"imdb-tt0371724": "The Hitchhiker's Guide to the Galaxy",
"isbn-9781439512982": "Isaac Asimov: The Complete Stories, Vol. 2",
}
def check_valid_id(id: str):
if not id.startswith(("isbn-", "imdb-")):
raise ValueError('Invalid ID format, it must start with "isbn-" or "imdb-"')
return id
@app.get("/items/")
async def read_items(
id: Annotated[str | None, AfterValidator(check_valid_id)] = None,
):
if id:
item = data.get(id)
else:
id, item = random.choice(list(data.items()))
return {"id": id, "name": item}

30
docs_src/query_params_str_validations/tutorial015_an_py39.py

@ -0,0 +1,30 @@
import random
from typing import Annotated, Union
from fastapi import FastAPI
from pydantic import AfterValidator
app = FastAPI()
data = {
"isbn-9781529046137": "The Hitchhiker's Guide to the Galaxy",
"imdb-tt0371724": "The Hitchhiker's Guide to the Galaxy",
"isbn-9781439512982": "Isaac Asimov: The Complete Stories, Vol. 2",
}
def check_valid_id(id: str):
if not id.startswith(("isbn-", "imdb-")):
raise ValueError('Invalid ID format, it must start with "isbn-" or "imdb-"')
return id
@app.get("/items/")
async def read_items(
id: Annotated[Union[str, None], AfterValidator(check_valid_id)] = None,
):
if id:
item = data.get(id)
else:
id, item = random.choice(list(data.items()))
return {"id": id, "name": item}

2
docs_src/security/tutorial004.py

@ -95,7 +95,7 @@ async def get_current_user(token: str = Depends(oauth2_scheme)):
)
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub")
username = payload.get("sub")
if username is None:
raise credentials_exception
token_data = TokenData(username=username)

2
docs_src/security/tutorial004_an.py

@ -96,7 +96,7 @@ async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]):
)
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub")
username = payload.get("sub")
if username is None:
raise credentials_exception
token_data = TokenData(username=username)

2
docs_src/security/tutorial004_an_py310.py

@ -95,7 +95,7 @@ async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]):
)
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub")
username = payload.get("sub")
if username is None:
raise credentials_exception
token_data = TokenData(username=username)

2
docs_src/security/tutorial004_an_py39.py

@ -95,7 +95,7 @@ async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]):
)
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub")
username = payload.get("sub")
if username is None:
raise credentials_exception
token_data = TokenData(username=username)

2
docs_src/security/tutorial004_py310.py

@ -94,7 +94,7 @@ async def get_current_user(token: str = Depends(oauth2_scheme)):
)
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub")
username = payload.get("sub")
if username is None:
raise credentials_exception
token_data = TokenData(username=username)

2
docs_src/security/tutorial005_an.py

@ -117,7 +117,7 @@ async def get_current_user(
)
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub")
username = payload.get("sub")
if username is None:
raise credentials_exception
token_scopes = payload.get("scopes", [])

2
docs_src/security/tutorial005_an_py310.py

@ -116,7 +116,7 @@ async def get_current_user(
)
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub")
username = payload.get("sub")
if username is None:
raise credentials_exception
token_scopes = payload.get("scopes", [])

6
docs_src/security/tutorial005_an_py39.py

@ -1,5 +1,5 @@
from datetime import datetime, timedelta, timezone
from typing import Annotated, List, Union
from typing import Annotated, Union
import jwt
from fastapi import Depends, FastAPI, HTTPException, Security, status
@ -44,7 +44,7 @@ class Token(BaseModel):
class TokenData(BaseModel):
username: Union[str, None] = None
scopes: List[str] = []
scopes: list[str] = []
class User(BaseModel):
@ -116,7 +116,7 @@ async def get_current_user(
)
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub")
username = payload.get("sub")
if username is None:
raise credentials_exception
token_scopes = payload.get("scopes", [])

2
fastapi/__init__.py

@ -1,6 +1,6 @@
"""FastAPI framework, high performance, easy to learn, fast to code, ready for production"""
__version__ = "0.115.8"
__version__ = "0.115.11"
from starlette import status as status

42
fastapi/dependencies/utils.py

@ -136,9 +136,9 @@ def get_param_sub_dependant(
def get_parameterless_sub_dependant(*, depends: params.Depends, path: str) -> Dependant:
assert callable(
depends.dependency
), "A parameter-less dependency must have a callable dependency"
assert callable(depends.dependency), (
"A parameter-less dependency must have a callable dependency"
)
return get_sub_dependant(depends=depends, dependency=depends.dependency, path=path)
@ -305,9 +305,9 @@ def get_dependant(
type_annotation=param_details.type_annotation,
dependant=dependant,
):
assert (
param_details.field is None
), f"Cannot specify multiple FastAPI annotations for {param_name!r}"
assert param_details.field is None, (
f"Cannot specify multiple FastAPI annotations for {param_name!r}"
)
continue
assert param_details.field is not None
if isinstance(param_details.field.field_info, params.Body):
@ -442,9 +442,9 @@ def analyze_param(
),
):
assert depends is None, f"Cannot specify `Depends` for type {type_annotation!r}"
assert (
field_info is None
), f"Cannot specify FastAPI annotation for type {type_annotation!r}"
assert field_info is None, (
f"Cannot specify FastAPI annotation for type {type_annotation!r}"
)
# Handle default assignations, neither field_info nor depends was not found in Annotated nor default value
elif field_info is None and depends is None:
default_value = value if value is not inspect.Signature.empty else RequiredParam
@ -497,9 +497,9 @@ def analyze_param(
field_info=field_info,
)
if is_path_param:
assert is_scalar_field(
field=field
), "Path params must be of one of the supported types"
assert is_scalar_field(field=field), (
"Path params must be of one of the supported types"
)
elif isinstance(field_info, params.Query):
assert (
is_scalar_field(field)
@ -524,9 +524,9 @@ def add_param_to_fields(*, field: ModelField, dependant: Dependant) -> None:
elif field_info_in == params.ParamTypes.header:
dependant.header_params.append(field)
else:
assert (
field_info_in == params.ParamTypes.cookie
), f"non-body parameters must be in path, query, header or cookie: {field.name}"
assert field_info_in == params.ParamTypes.cookie, (
f"non-body parameters must be in path, query, header or cookie: {field.name}"
)
dependant.cookie_params.append(field)
@ -812,9 +812,9 @@ def request_params_to_args(
if single_not_embedded_field:
field_info = first_field.field_info
assert isinstance(
field_info, params.Param
), "Params must be subclasses of Param"
assert isinstance(field_info, params.Param), (
"Params must be subclasses of Param"
)
loc: Tuple[str, ...] = (field_info.in_.value,)
v_, errors_ = _validate_value_with_model_field(
field=first_field, value=params_to_process, values=values, loc=loc
@ -824,9 +824,9 @@ def request_params_to_args(
for field in fields:
value = _get_multidict_value(field, received_params)
field_info = field.field_info
assert isinstance(
field_info, params.Param
), "Params must be subclasses of Param"
assert isinstance(field_info, params.Param), (
"Params must be subclasses of Param"
)
loc = (field_info.in_.value, field.alias)
v_, errors_ = _validate_value_with_model_field(
field=field, value=value, values=values, loc=loc

12
fastapi/openapi/utils.py

@ -364,9 +364,9 @@ def get_openapi_path(
openapi_response = operation_responses.setdefault(
status_code_key, {}
)
assert isinstance(
process_response, dict
), "An additional response must be a dict"
assert isinstance(process_response, dict), (
"An additional response must be a dict"
)
field = route.response_fields.get(additional_status_code)
additional_field_schema: Optional[Dict[str, Any]] = None
if field:
@ -434,9 +434,9 @@ def get_fields_from_routes(
route, routing.APIRoute
):
if route.body_field:
assert isinstance(
route.body_field, ModelField
), "A request body must be a Pydantic Field"
assert isinstance(route.body_field, ModelField), (
"A request body must be a Pydantic Field"
)
body_fields_from_routes.append(route.body_field)
if route.response_field:
responses_from_routes.append(route.response_field)

24
fastapi/routing.py

@ -504,9 +504,9 @@ class APIRoute(routing.Route):
status_code = int(status_code)
self.status_code = status_code
if self.response_model:
assert is_body_allowed_for_status_code(
status_code
), f"Status code {status_code} must not have a response body"
assert is_body_allowed_for_status_code(status_code), (
f"Status code {status_code} must not have a response body"
)
response_name = "Response_" + self.unique_id
self.response_field = create_model_field(
name=response_name,
@ -537,9 +537,9 @@ class APIRoute(routing.Route):
assert isinstance(response, dict), "An additional response must be a dict"
model = response.get("model")
if model:
assert is_body_allowed_for_status_code(
additional_status_code
), f"Status code {additional_status_code} must not have a response body"
assert is_body_allowed_for_status_code(additional_status_code), (
f"Status code {additional_status_code} must not have a response body"
)
response_name = f"Response_{additional_status_code}_{self.unique_id}"
response_field = create_model_field(
name=response_name, type_=model, mode="serialization"
@ -844,9 +844,9 @@ class APIRouter(routing.Router):
)
if prefix:
assert prefix.startswith("/"), "A path prefix must start with '/'"
assert not prefix.endswith(
"/"
), "A path prefix must not end with '/', as the routes will start with '/'"
assert not prefix.endswith("/"), (
"A path prefix must not end with '/', as the routes will start with '/'"
)
self.prefix = prefix
self.tags: List[Union[str, Enum]] = tags or []
self.dependencies = list(dependencies or [])
@ -1256,9 +1256,9 @@ class APIRouter(routing.Router):
"""
if prefix:
assert prefix.startswith("/"), "A path prefix must start with '/'"
assert not prefix.endswith(
"/"
), "A path prefix must not end with '/', as the routes will start with '/'"
assert not prefix.endswith("/"), (
"A path prefix must not end with '/', as the routes will start with '/'"
)
else:
for r in router.routes:
path = getattr(r, "path") # noqa: B009

11
fastapi/security/http.py

@ -413,8 +413,11 @@ class HTTPDigest(HTTPBase):
else:
return None
if scheme.lower() != "digest":
raise HTTPException(
status_code=HTTP_403_FORBIDDEN,
detail="Invalid authentication credentials",
)
if self.auto_error:
raise HTTPException(
status_code=HTTP_403_FORBIDDEN,
detail="Invalid authentication credentials",
)
else:
return None
return HTTPAuthorizationCredentials(scheme=scheme, credentials=credentials)

2
pyproject.toml

@ -43,7 +43,7 @@ classifiers = [
"Topic :: Internet :: WWW/HTTP",
]
dependencies = [
"starlette>=0.40.0,<0.46.0",
"starlette>=0.40.0,<0.47.0",
"pydantic>=1.7.4,!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0",
"typing-extensions>=4.8.0",
]

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

Loading…
Cancel
Save