Browse Source

Merge branch 'master' of https://github.com/Zhongheng-Cheng/fastapi into translate/manually

pull/13324/head
Zhongheng-Cheng 1 week ago
parent
commit
70236e49bd
  1. 5
      .github/workflows/deploy-docs.yml
  2. 2
      .pre-commit-config.yaml
  3. 3
      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. 5
      docs/en/data/external_links.yml
  12. 177
      docs/en/data/github_sponsors.yml
  13. 3
      docs/en/data/members.yml
  14. 574
      docs/en/data/people.yml
  15. 12
      docs/en/data/sponsors.yml
  16. 336
      docs/en/data/topic_repos.yml
  17. 199
      docs/en/data/translation_reviewers.yml
  18. 56
      docs/en/data/translators.yml
  19. 15
      docs/en/docs/advanced/index.md
  20. BIN
      docs/en/docs/img/sponsors/coderabbit-banner.png
  21. BIN
      docs/en/docs/img/sponsors/coderabbit.png
  22. BIN
      docs/en/docs/img/sponsors/lambdatest.png
  23. 2
      docs/en/docs/index.md
  24. 123
      docs/en/docs/release-notes.md
  25. 2
      docs/en/docs/tutorial/body-multiple-params.md
  26. 16
      docs/en/docs/tutorial/header-param-models.md
  27. 2
      docs/en/docs/tutorial/middleware.md
  28. 181
      docs/en/docs/tutorial/query-params-str-validations.md
  29. 10
      docs/en/docs/tutorial/response-status-code.md
  30. 4
      docs/en/docs/virtual-environments.md
  31. 76
      docs/en/mkdocs.yml
  32. 6
      docs/en/overrides/main.html
  33. 2
      docs/es/docs/index.md
  34. 16
      docs/es/docs/tutorial/query-params-str-validations.md
  35. 8
      docs/fa/docs/index.md
  36. 2
      docs/fr/docs/index.md
  37. 6
      docs/he/docs/index.md
  38. 2
      docs/hu/docs/index.md
  39. 2
      docs/id/docs/index.md
  40. 14
      docs/it/docs/index.md
  41. 13
      docs/ja/docs/index.md
  42. 77
      docs/ja/docs/tutorial/cookie-param-models.md
  43. 68
      docs/ja/docs/tutorial/query-param-models.md
  44. 831
      docs/ja/docs/virtual-environments.md
  45. 313
      docs/ko/docs/advanced/custom-response.md
  46. 287
      docs/ko/docs/help-fastapi.md
  47. 11
      docs/ko/docs/index.md
  48. 275
      docs/ko/docs/tutorial/dependencies/dependencies-with-yield.md
  49. 273
      docs/ko/docs/tutorial/security/oauth2-jwt.md
  50. 18
      docs/ko/docs/tutorial/security/simple-oauth2.md
  51. 2
      docs/nl/docs/index.md
  52. 11
      docs/pl/docs/index.md
  53. 2
      docs/pt/docs/index.md
  54. 48
      docs/ru/docs/advanced/response-cookies.md
  55. 6
      docs/ru/docs/index.md
  56. 74
      docs/ru/docs/tutorial/middleware.md
  57. 28
      docs/ru/docs/tutorial/query-params-str-validations.md
  58. 2
      docs/tr/docs/index.md
  59. 2
      docs/uk/docs/index.md
  60. 170
      docs/uk/docs/tutorial/body-multiple-params.md
  61. 245
      docs/uk/docs/tutorial/body-nested-models.md
  62. 76
      docs/uk/docs/tutorial/cookie-param-models.md
  63. 112
      docs/uk/docs/tutorial/debugging.md
  64. 58
      docs/uk/docs/tutorial/header-param-models.md
  65. 91
      docs/uk/docs/tutorial/header-params.md
  66. 120
      docs/uk/docs/tutorial/metadata.md
  67. 261
      docs/uk/docs/tutorial/path-params.md
  68. 192
      docs/uk/docs/tutorial/query-params.md
  69. 175
      docs/uk/docs/tutorial/request-files.md
  70. 78
      docs/uk/docs/tutorial/request-form-models.md
  71. 41
      docs/uk/docs/tutorial/request-forms-and-files.md
  72. 73
      docs/uk/docs/tutorial/request-forms.md
  73. 100
      docs/uk/docs/tutorial/response-status-code.md
  74. 240
      docs/uk/docs/tutorial/testing.md
  75. 17
      docs/vi/docs/deployment/cloud.md
  76. 21
      docs/vi/docs/deployment/index.md
  77. 93
      docs/vi/docs/deployment/versions.md
  78. 2
      docs/vi/docs/index.md
  79. 40
      docs/vi/docs/tutorial/static-files.md
  80. 2
      docs/yo/docs/index.md
  81. 2
      docs/zh-hant/docs/index.md
  82. 8
      docs/zh/docs/index.md
  83. 95
      docs/zh/docs/tutorial/first-steps.md
  84. 27
      docs/zh/docs/tutorial/query-params-str-validations.md
  85. 2
      docs_src/configure_swagger_ui/tutorial002.py
  86. 19
      docs_src/header_param_models/tutorial003.py
  87. 22
      docs_src/header_param_models/tutorial003_an.py
  88. 21
      docs_src/header_param_models/tutorial003_an_py310.py
  89. 21
      docs_src/header_param_models/tutorial003_an_py39.py
  90. 17
      docs_src/header_param_models/tutorial003_py310.py
  91. 19
      docs_src/header_param_models/tutorial003_py39.py
  92. 11
      docs_src/query_params_str_validations/tutorial006b.py
  93. 12
      docs_src/query_params_str_validations/tutorial006b_an.py
  94. 13
      docs_src/query_params_str_validations/tutorial006b_an_py39.py
  95. 2
      docs_src/query_params_str_validations/tutorial006c.py
  96. 2
      docs_src/query_params_str_validations/tutorial006c_an.py
  97. 2
      docs_src/query_params_str_validations/tutorial006c_an_py310.py
  98. 2
      docs_src/query_params_str_validations/tutorial006c_an_py39.py
  99. 2
      docs_src/query_params_str_validations/tutorial006c_py310.py
  100. 11
      docs_src/query_params_str_validations/tutorial006d.py

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.11.2
hooks:
- id: ruff
args:

3
README.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">
@ -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

5
docs/en/data/external_links.yml

@ -411,3 +411,8 @@ Talks:
author_link: https://twitter.com/chriswithers13
link: https://www.youtube.com/watch?v=3DLwPcrE5mA
title: 'PyCon UK 2019: FastAPI from the ground up'
Taiwanese:
- author: Bluewen
author_link: https://github.com/blueswen
link: https://www.youtube.com/watch?v=y3sumuoDq4w
title: 'PyCon TW 2024: 全方位強化 Python 服務可觀測性:以 FastAPI 和 Grafana Stack 為例'

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

574
docs/en/data/people.yml

@ -1,11 +1,11 @@
maintainers:
- login: tiangolo
answers: 1894
answers: 1897
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
url: https://github.com/tiangolo
experts:
- login: tiangolo
count: 1894
count: 1897
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
url: https://github.com/tiangolo
- login: github-actions
@ -13,11 +13,11 @@ experts:
avatarUrl: https://avatars.githubusercontent.com/in/15368?v=4
url: https://github.com/apps/github-actions
- login: Kludex
count: 645
count: 654
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=df8a3f06ba8f55ae1967a3e2d5ed882903a4e330&v=4
url: https://github.com/Kludex
- login: jgould22
count: 250
count: 263
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
url: https://github.com/jgould22
- login: dmontagu
@ -25,7 +25,7 @@ experts:
avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=540f30c937a6450812628b9592a1dfe91bbe148e&v=4
url: https://github.com/dmontagu
- login: YuriiMotov
count: 223
count: 238
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4
url: https://github.com/YuriiMotov
- login: Mause
@ -34,7 +34,7 @@ experts:
url: https://github.com/Mause
- login: ycd
count: 217
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
- login: JarroVGIT
count: 192
@ -46,14 +46,14 @@ experts:
url: https://github.com/euri10
- login: iudeen
count: 128
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
- login: phy25
count: 126
avatarUrl: https://avatars.githubusercontent.com/u/331403?v=4
url: https://github.com/phy25
- login: JavierSanchezCastro
count: 85
count: 91
avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
url: https://github.com/JavierSanchezCastro
- login: raphaelauv
@ -69,7 +69,7 @@ experts:
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=b0f2c37142f4b762e41ad65dc49581813422bd71&v=4
url: https://github.com/ArcLightSlavik
- login: n8sty
count: 66
count: 67
avatarUrl: https://avatars.githubusercontent.com/u/2964996?v=4
url: https://github.com/n8sty
- login: falkben
@ -80,46 +80,46 @@ experts:
count: 50
avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
url: https://github.com/acidjunk
- login: sm-Fifteen
count: 49
avatarUrl: https://avatars.githubusercontent.com/u/516999?u=437c0c5038558c67e887ccd863c1ba0f846c03da&v=4
url: https://github.com/sm-Fifteen
- login: yinziyan1206
count: 49
avatarUrl: https://avatars.githubusercontent.com/u/37829370?u=da44ca53aefd5c23f346fab8e9fd2e108294c179&v=4
url: https://github.com/yinziyan1206
- login: sm-Fifteen
count: 49
avatarUrl: https://avatars.githubusercontent.com/u/516999?u=437c0c5038558c67e887ccd863c1ba0f846c03da&v=4
url: https://github.com/sm-Fifteen
- login: luzzodev
count: 48
avatarUrl: https://avatars.githubusercontent.com/u/27291415?u=5607ae1ce75c5f54f09500ca854227f7bfd2033b&v=4
url: https://github.com/luzzodev
- login: adriangb
count: 46
avatarUrl: https://avatars.githubusercontent.com/u/1755071?u=612704256e38d6ac9cbed24f10e4b6ac2da74ecb&v=4
url: https://github.com/adriangb
- login: Dustyposa
count: 45
avatarUrl: https://avatars.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4
url: https://github.com/Dustyposa
- login: insomnes
count: 45
avatarUrl: https://avatars.githubusercontent.com/u/16958893?u=f8be7088d5076d963984a21f95f44e559192d912&v=4
url: https://github.com/insomnes
- login: odiseo0
count: 43
avatarUrl: https://avatars.githubusercontent.com/u/87550035?u=241a71f6b7068738b81af3e57f45ffd723538401&v=4
url: https://github.com/odiseo0
- login: Dustyposa
count: 45
avatarUrl: https://avatars.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4
url: https://github.com/Dustyposa
- login: frankie567
count: 43
avatarUrl: https://avatars.githubusercontent.com/u/1144727?u=c159fe047727aedecbbeeaa96a1b03ceb9d39add&v=4
url: https://github.com/frankie567
- login: odiseo0
count: 43
avatarUrl: https://avatars.githubusercontent.com/u/87550035?u=241a71f6b7068738b81af3e57f45ffd723538401&v=4
url: https://github.com/odiseo0
- login: sinisaos
count: 40
avatarUrl: https://avatars.githubusercontent.com/u/30960668?v=4
url: https://github.com/sinisaos
- login: includeamin
count: 40
avatarUrl: https://avatars.githubusercontent.com/u/11836741?u=8bd5ef7e62fe6a82055e33c4c0e0a7879ff8cfb6&v=4
url: https://github.com/includeamin
- login: sinisaos
count: 39
avatarUrl: https://avatars.githubusercontent.com/u/30960668?v=4
url: https://github.com/sinisaos
- login: luzzodev
count: 37
avatarUrl: https://avatars.githubusercontent.com/u/27291415?v=4
url: https://github.com/luzzodev
- login: chbndrhnns
count: 37
avatarUrl: https://avatars.githubusercontent.com/u/7534547?v=4
@ -160,10 +160,10 @@ experts:
count: 22
avatarUrl: https://avatars.githubusercontent.com/u/4216559?u=360a36fb602cded27273cbfc0afc296eece90662&v=4
url: https://github.com/nymous
- login: acnebs
- login: connebs
count: 22
avatarUrl: https://avatars.githubusercontent.com/u/9054108?v=4
url: https://github.com/acnebs
avatarUrl: https://avatars.githubusercontent.com/u/9054108?u=e151d5f545a3395136d711c227c22032fda67cfa&v=4
url: https://github.com/connebs
- login: chrisK824
count: 22
avatarUrl: https://avatars.githubusercontent.com/u/79946379?u=03d85b22d696a58a9603e55fbbbe2de6b0f4face&v=4
@ -188,14 +188,14 @@ experts:
count: 19
avatarUrl: https://avatars.githubusercontent.com/u/10840422?u=45f015f95e1c0f06df602be4ab688d4b854cc8a8&v=4
url: https://github.com/estebanx64
- login: sehraramiz
count: 18
avatarUrl: https://avatars.githubusercontent.com/u/14166324?u=8fac65e84dfff24245d304a5b5b09f7b5bd69dc9&v=4
url: https://github.com/sehraramiz
- login: zoliknemet
count: 18
avatarUrl: https://avatars.githubusercontent.com/u/22326718?u=31ba446ac290e23e56eea8e4f0c558aaf0b40779&v=4
url: https://github.com/zoliknemet
- login: sehraramiz
count: 18
avatarUrl: https://avatars.githubusercontent.com/u/14166324?u=8fac65e84dfff24245d304a5b5b09f7b5bd69dc9&v=4
url: https://github.com/sehraramiz
- login: retnikt
count: 18
avatarUrl: https://avatars.githubusercontent.com/u/24581770?v=4
@ -216,6 +216,10 @@ experts:
count: 17
avatarUrl: https://avatars.githubusercontent.com/u/28262306?u=e19427d8dc296d6950e9c424adacc92d37496fe9&v=4
url: https://github.com/nkhitrov
- login: alv2017
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
url: https://github.com/alv2017
- login: jonatasoli
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/26334101?u=071c062d2861d3dd127f6b4a5258cd8ef55d4c50&v=4
@ -224,6 +228,10 @@ experts:
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/41964673?u=9f2174f9d61c15c6e3a4c9e3aeee66f711ce311f&v=4
url: https://github.com/dstlny
- login: abhint
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/25699289?u=b5d219277b4d001ac26fb8be357fddd88c29d51b&v=4
url: https://github.com/abhint
- login: ceb10n
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
@ -236,100 +244,96 @@ experts:
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/33907262?u=2721fb37014d50daf473267c808aa678ecaefe09&v=4
url: https://github.com/simondale00
- login: ghost
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/10137?u=b1951d34a583cf12ec0d3b0781ba19be97726318&v=4
url: https://github.com/ghost
- login: abhint
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/25699289?u=b5d219277b4d001ac26fb8be357fddd88c29d51b&v=4
url: https://github.com/abhint
last_month_experts:
- login: Kludex
count: 14
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=df8a3f06ba8f55ae1967a3e2d5ed882903a4e330&v=4
url: https://github.com/Kludex
- login: YuriiMotov
- login: jgould22
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
url: https://github.com/jgould22
- login: alv2017
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4
url: https://github.com/YuriiMotov
- login: sehraramiz
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/14166324?u=8fac65e84dfff24245d304a5b5b09f7b5bd69dc9&v=4
url: https://github.com/sehraramiz
avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
url: https://github.com/alv2017
- login: luzzodev
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/27291415?v=4
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/27291415?u=5607ae1ce75c5f54f09500ca854227f7bfd2033b&v=4
url: https://github.com/luzzodev
- login: yokwejuste
- login: YuriiMotov
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4
url: https://github.com/YuriiMotov
- login: Kludex
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/71908316?u=592c1e42aa0ee5cb94890e0b863e2acc78cc3bbc&v=4
url: https://github.com/yokwejuste
- login: alv2017
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
url: https://github.com/alv2017
- login: Trinkes
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/9466879?v=4
url: https://github.com/Trinkes
- login: PREPONDERANCE
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/112809059?u=30ab12dc9ddba2f94ab90e6ad4ad8bc5cfa7fccd&v=4
url: https://github.com/PREPONDERANCE
- login: nbx3
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/34649527?u=943812f69e0d40adbd3fa1c9b8ef50dd971a2a45&v=4
url: https://github.com/nbx3
- login: XiaoXinYo
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=df8a3f06ba8f55ae1967a3e2d5ed882903a4e330&v=4
url: https://github.com/Kludex
- login: JavierSanchezCastro
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
url: https://github.com/JavierSanchezCastro
- login: tiangolo
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
url: https://github.com/tiangolo
- login: Ale-Cas
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/56395004?u=b3b7cb758997f283c271a581833e407229dab82c&v=4
url: https://github.com/XiaoXinYo
- login: iloveitaly
avatarUrl: https://avatars.githubusercontent.com/u/64859146?u=d52a6ecf8d83d2927e2ae270bdfcc83495dba8c9&v=4
url: https://github.com/Ale-Cas
- login: vtgn
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/150855?v=4
url: https://github.com/iloveitaly
avatarUrl: https://avatars.githubusercontent.com/u/112889052?v=4
url: https://github.com/vtgn
three_months_experts:
- login: luzzodev
count: 33
avatarUrl: https://avatars.githubusercontent.com/u/27291415?v=4
url: https://github.com/luzzodev
- login: YuriiMotov
count: 31
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4
url: https://github.com/YuriiMotov
- login: Kludex
count: 24
count: 25
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=df8a3f06ba8f55ae1967a3e2d5ed882903a4e330&v=4
url: https://github.com/Kludex
- login: luzzodev
count: 19
avatarUrl: https://avatars.githubusercontent.com/u/27291415?u=5607ae1ce75c5f54f09500ca854227f7bfd2033b&v=4
url: https://github.com/luzzodev
- login: alv2017
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
url: https://github.com/alv2017
- login: jgould22
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
url: https://github.com/jgould22
- login: sehraramiz
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/14166324?u=8fac65e84dfff24245d304a5b5b09f7b5bd69dc9&v=4
url: https://github.com/sehraramiz
- login: estebanx64
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/10840422?u=45f015f95e1c0f06df602be4ab688d4b854cc8a8&v=4
url: https://github.com/estebanx64
- login: yvallois
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/36999744?v=4
url: https://github.com/yvallois
- login: JavierSanchezCastro
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
url: https://github.com/JavierSanchezCastro
- login: tiangolo
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
url: https://github.com/tiangolo
- login: yokwejuste
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/71908316?u=592c1e42aa0ee5cb94890e0b863e2acc78cc3bbc&v=4
url: https://github.com/yokwejuste
- login: jgould22
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
url: https://github.com/jgould22
- login: alv2017
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
url: https://github.com/alv2017
- login: viniciusCalcantara
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/108818737?u=3d7ffe5808843ee4372f9cc5a559ff1674cf1792&v=4
url: https://github.com/viniciusCalcantara
- login: SobikXexe
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/87701130?v=4
url: https://github.com/SobikXexe
- login: Ale-Cas
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/64859146?u=d52a6ecf8d83d2927e2ae270bdfcc83495dba8c9&v=4
url: https://github.com/Ale-Cas
- login: vtgn
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/112889052?v=4
url: https://github.com/vtgn
- login: Trinkes
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/9466879?v=4
@ -344,117 +348,81 @@ three_months_experts:
url: https://github.com/nbx3
- login: XiaoXinYo
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/56395004?u=b3b7cb758997f283c271a581833e407229dab82c&v=4
avatarUrl: https://avatars.githubusercontent.com/u/56395004?u=1eebf5ce25a8067f7bfa6251a24f667be492d9d6&v=4
url: https://github.com/XiaoXinYo
- login: JavierSanchezCastro
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
url: https://github.com/JavierSanchezCastro
- login: iloveitaly
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/150855?v=4
url: https://github.com/iloveitaly
- login: LincolnPuzey
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/18750802?v=4
url: https://github.com/LincolnPuzey
- login: Knighthawk-Leo
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/72437494?u=27c68db94a3107b605e603cc136f4ba83f0106d5&v=4
url: https://github.com/Knighthawk-Leo
- login: gelezo43
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/40732698?u=611f39d3c1d2f4207a590937a78c1f10eed6232c&v=4
url: https://github.com/gelezo43
- login: AliYmn
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/18416653?u=98c1fca46c7e4dabe8c39d17b5e55d1511d41cf9&v=4
url: https://github.com/AliYmn
- login: RichieB2B
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/1461970?u=edaa57d1077705244ea5c9244f4783d94ff11f12&v=4
url: https://github.com/RichieB2B
- login: Synrom
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/30272537?v=4
url: https://github.com/Synrom
- login: iiotsrc
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/131771119?u=bcaf2559ef6266af70b151b7fda31a1ee3dbecb3&v=4
url: https://github.com/iiotsrc
- login: Kfir-G
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/57500876?u=0cd29db046a17f12f382d398141319fca7ff230a&v=4
url: https://github.com/Kfir-G
six_months_experts:
- login: YuriiMotov
count: 72
count: 63
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4
url: https://github.com/YuriiMotov
- login: luzzodev
count: 48
avatarUrl: https://avatars.githubusercontent.com/u/27291415?u=5607ae1ce75c5f54f09500ca854227f7bfd2033b&v=4
url: https://github.com/luzzodev
- login: Kludex
count: 40
count: 48
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=df8a3f06ba8f55ae1967a3e2d5ed882903a4e330&v=4
url: https://github.com/Kludex
- login: luzzodev
count: 37
avatarUrl: https://avatars.githubusercontent.com/u/27291415?v=4
url: https://github.com/luzzodev
- login: sinisaos
count: 37
count: 23
avatarUrl: https://avatars.githubusercontent.com/u/30960668?v=4
url: https://github.com/sinisaos
- login: jgould22
count: 17
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
url: https://github.com/jgould22
- login: JavierSanchezCastro
count: 16
count: 17
avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
url: https://github.com/JavierSanchezCastro
- login: alv2017
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
url: https://github.com/alv2017
- login: Kfir-G
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/57500876?u=0cd29db046a17f12f382d398141319fca7ff230a&v=4
url: https://github.com/Kfir-G
- login: tiangolo
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
url: https://github.com/tiangolo
- login: sehraramiz
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/14166324?u=8fac65e84dfff24245d304a5b5b09f7b5bd69dc9&v=4
url: https://github.com/sehraramiz
- login: ceb10n
count: 10
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
url: https://github.com/ceb10n
- login: estebanx64
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/10840422?u=45f015f95e1c0f06df602be4ab688d4b854cc8a8&v=4
url: https://github.com/estebanx64
- login: tiangolo
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
url: https://github.com/tiangolo
- login: yvallois
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/36999744?v=4
url: https://github.com/yvallois
- login: n8sty
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/2964996?v=4
url: https://github.com/n8sty
- login: TomFaulkner
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/14956620?v=4
url: https://github.com/TomFaulkner
- login: yokwejuste
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/71908316?u=592c1e42aa0ee5cb94890e0b863e2acc78cc3bbc&v=4
url: https://github.com/yokwejuste
- login: jgould22
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
url: https://github.com/jgould22
- login: alv2017
- login: n8sty
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
url: https://github.com/alv2017
avatarUrl: https://avatars.githubusercontent.com/u/2964996?v=4
url: https://github.com/n8sty
- login: viniciusCalcantara
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/108818737?u=3d7ffe5808843ee4372f9cc5a559ff1674cf1792&v=4
url: https://github.com/viniciusCalcantara
- login: SobikXexe
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/87701130?v=4
url: https://github.com/SobikXexe
- login: pawelad
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/7062874?u=d27dc220545a8401ad21840590a97d474d7101e6&v=4
@ -467,26 +435,18 @@ six_months_experts:
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/48672727?u=34d7b4ade252687d22a27cf53037b735b244bfc1&v=4
url: https://github.com/Isuxiz
- login: bertomaniac
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/10235051?u=14484a96833228a7b29fee4a7916d411c242c4f6&v=4
url: https://github.com/bertomaniac
- login: PhysicallyActive
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/160476156?u=7a8e44f4a43d3bba636f795bb7d9476c9233b4d8&v=4
url: https://github.com/PhysicallyActive
- login: Minibrams
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/8108085?u=b028dbc308fa8485e0e2e9402b3d03d8deb22bf9&v=4
url: https://github.com/Minibrams
- login: AIdjis
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/88404339?u=2a80d80b054e9228391e32fb9bb39571509dab6a&v=4
url: https://github.com/AIdjis
- login: svlandeg
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4
url: https://github.com/svlandeg
- login: Ale-Cas
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/64859146?u=d52a6ecf8d83d2927e2ae270bdfcc83495dba8c9&v=4
url: https://github.com/Ale-Cas
- login: vtgn
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/112889052?v=4
url: https://github.com/vtgn
- login: Trinkes
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/9466879?v=4
@ -499,26 +459,10 @@ six_months_experts:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/34649527?u=943812f69e0d40adbd3fa1c9b8ef50dd971a2a45&v=4
url: https://github.com/nbx3
- login: yanggeorge
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/2434407?v=4
url: https://github.com/yanggeorge
- login: XiaoXinYo
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/56395004?u=b3b7cb758997f283c271a581833e407229dab82c&v=4
avatarUrl: https://avatars.githubusercontent.com/u/56395004?u=1eebf5ce25a8067f7bfa6251a24f667be492d9d6&v=4
url: https://github.com/XiaoXinYo
- login: pythonweb2
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/32141163?v=4
url: https://github.com/pythonweb2
- login: slafs
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/210173?v=4
url: https://github.com/slafs
- login: AmirHmZz
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/38752106?u=07f80e451bda00a9492bbc764e49d24ad3ada8cc&v=4
url: https://github.com/AmirHmZz
- login: iloveitaly
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/150855?v=4
@ -527,10 +471,6 @@ six_months_experts:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/18750802?v=4
url: https://github.com/LincolnPuzey
- login: alejsdev
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=356f39ff3f0211c720b06d3dbb060e98884085e3&v=4
url: https://github.com/alejsdev
- login: Knighthawk-Leo
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/72437494?u=27c68db94a3107b605e603cc136f4ba83f0106d5&v=4
@ -559,10 +499,6 @@ six_months_experts:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/30272537?v=4
url: https://github.com/Synrom
- login: ecly
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/8410422?v=4
url: https://github.com/ecly
- login: iiotsrc
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/131771119?u=bcaf2559ef6266af70b151b7fda31a1ee3dbecb3&v=4
@ -575,14 +511,6 @@ six_months_experts:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/47495003?u=6e225cb42c688d0cd70e65c6baedb9f5922b1178&v=4
url: https://github.com/jd-solanki
- login: AumGupta
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/86357151?u=7d05aa606c0611a18f4db16cf26361ce10a6e195&v=4
url: https://github.com/AumGupta
- login: DeoLeung
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/3764720?u=4c222ef513814de4c7fb3736d0a7adf11d953d43&v=4
url: https://github.com/DeoLeung
- login: Reemyos
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/44867003?v=4
@ -591,77 +519,61 @@ six_months_experts:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/37678115?u=a608798b5bd0034183a9c430ebb42fb266db86ce&v=4
url: https://github.com/deight93
- login: PhysicallyActive
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/160476156?u=7a8e44f4a43d3bba636f795bb7d9476c9233b4d8&v=4
url: https://github.com/PhysicallyActive
- login: Jkrox
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/83181939?u=d6a922d97129f7f3916d6a1c166bc011b3a72b7f&v=4
url: https://github.com/Jkrox
- login: mmzeynalli
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/33568903?u=19efd0c0722730b83a70b7c86c36e5b7d83e07d2&v=4
url: https://github.com/mmzeynalli
- login: ddahan
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/1933516?u=1d200a620e8d6841df017e9f2bb7efb58b580f40&v=4
url: https://github.com/ddahan
- login: jfeaver
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/1091338?u=0bcba366447d8fadad63f6705a52d128da4c7ec2&v=4
url: https://github.com/jfeaver
- login: Wurstnase
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/8709415?u=f479af475a97aee9a1dab302cfc35d07e9ea245f&v=4
url: https://github.com/Wurstnase
- login: tristan
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/1412?u=aab8aaa4cc0f1210ac45fc93873a5909d314c965&v=4
url: https://github.com/tristan
- login: chandanch
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/8663552?u=afc484bc0a952c83f1fb6a1583cda443f807cd66&v=4
url: https://github.com/chandanch
- login: rvishruth
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/79176273?v=4
url: https://github.com/rvishruth
- login: mattmess1221
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/3409962?u=723662989f2027755e67d200137c13c53ae154ac&v=4
url: https://github.com/mattmess1221
one_year_experts:
- login: YuriiMotov
count: 223
count: 214
avatarUrl: https://avatars.githubusercontent.com/u/109919500?u=e83a39697a2d33ab2ec9bfbced794ee48bc29cec&v=4
url: https://github.com/YuriiMotov
- login: Kludex
count: 81
count: 66
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=df8a3f06ba8f55ae1967a3e2d5ed882903a4e330&v=4
url: https://github.com/Kludex
- login: luzzodev
count: 48
avatarUrl: https://avatars.githubusercontent.com/u/27291415?u=5607ae1ce75c5f54f09500ca854227f7bfd2033b&v=4
url: https://github.com/luzzodev
- login: sinisaos
count: 40
avatarUrl: https://avatars.githubusercontent.com/u/30960668?v=4
url: https://github.com/sinisaos
- login: JavierSanchezCastro
count: 47
count: 39
avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
url: https://github.com/JavierSanchezCastro
- login: jgould22
count: 42
count: 35
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
url: https://github.com/jgould22
- login: sinisaos
count: 39
avatarUrl: https://avatars.githubusercontent.com/u/30960668?v=4
url: https://github.com/sinisaos
- login: luzzodev
count: 37
avatarUrl: https://avatars.githubusercontent.com/u/27291415?v=4
url: https://github.com/luzzodev
- login: tiangolo
count: 24
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
url: https://github.com/tiangolo
- login: alv2017
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
url: https://github.com/alv2017
- login: n8sty
count: 23
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/2964996?v=4
url: https://github.com/n8sty
- login: estebanx64
count: 19
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/10840422?u=45f015f95e1c0f06df602be4ab688d4b854cc8a8&v=4
url: https://github.com/estebanx64
- login: ceb10n
@ -682,10 +594,10 @@ one_year_experts:
url: https://github.com/Kfir-G
- login: mattmess1221
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/3409962?u=723662989f2027755e67d200137c13c53ae154ac&v=4
avatarUrl: https://avatars.githubusercontent.com/u/3409962?u=d22ea18aa8ea688af25a45df306134d593621a44&v=4
url: https://github.com/mattmess1221
- login: hasansezertasan
count: 10
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/13135006?u=99f0b0f0fc47e88e8abb337b4447357939ef93e7&v=4
url: https://github.com/hasansezertasan
- login: AIdjis
@ -704,22 +616,18 @@ one_year_experts:
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/32141163?v=4
url: https://github.com/pythonweb2
- login: acidjunk
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
url: https://github.com/acidjunk
- login: gustavosett
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/99373133?u=1739ca547c3d200f1b72450520bce46a97aab184&v=4
avatarUrl: https://avatars.githubusercontent.com/u/99373133?u=1382fe27034a0179f07cf989f63c4f23017f043c&v=4
url: https://github.com/gustavosett
- login: binbjz
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/8213913?u=22b68b7a0d5bf5e09c02084c0f5f53d7503114cd&v=4
url: https://github.com/binbjz
- login: chyok
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/32629225?u=3b7c30e8a09426a1b9284f6e8a0ae53a525596bf&v=4
url: https://github.com/chyok
- login: svlandeg
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4
url: https://github.com/svlandeg
- login: TomFaulkner
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/14956620?v=4
@ -728,42 +636,34 @@ one_year_experts:
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/71908316?u=592c1e42aa0ee5cb94890e0b863e2acc78cc3bbc&v=4
url: https://github.com/yokwejuste
- login: DeoLeung
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/3764720?u=4c222ef513814de4c7fb3736d0a7adf11d953d43&v=4
url: https://github.com/DeoLeung
- login: flo-at
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/564288?v=4
url: https://github.com/flo-at
- login: GodMoonGoodman
- login: acidjunk
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/29688727?u=7b251da620d999644c37c1feeb292d033eed7ad6&v=4
url: https://github.com/GodMoonGoodman
avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
url: https://github.com/acidjunk
- login: bertomaniac
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/10235051?u=14484a96833228a7b29fee4a7916d411c242c4f6&v=4
url: https://github.com/bertomaniac
- login: alv2017
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
url: https://github.com/alv2017
- login: msehnout
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/9369632?u=8c988f1b008a3f601385a3616f9327820f66e3a5&v=4
url: https://github.com/msehnout
- login: binbjz
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/8213913?u=22b68b7a0d5bf5e09c02084c0f5f53d7503114cd&v=4
url: https://github.com/binbjz
- login: viniciusCalcantara
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/108818737?u=3d7ffe5808843ee4372f9cc5a559ff1674cf1792&v=4
url: https://github.com/viniciusCalcantara
- login: SobikXexe
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/87701130?v=4
url: https://github.com/SobikXexe
- login: DeoLeung
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/3764720?u=4c222ef513814de4c7fb3736d0a7adf11d953d43&v=4
url: https://github.com/DeoLeung
- login: pawelad
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/7062874?u=d27dc220545a8401ad21840590a97d474d7101e6&v=4
url: https://github.com/pawelad
- login: ThirVondukr
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/50728601?u=167c0bd655e52817082e50979a86d2f98f95b1a3&v=4
url: https://github.com/ThirVondukr
- login: dbfreem
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/9778569?u=f2f1e9135b5e4f1b0c6821a548b17f97572720fc&v=4
@ -772,10 +672,6 @@ one_year_experts:
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/48672727?u=34d7b4ade252687d22a27cf53037b735b244bfc1&v=4
url: https://github.com/Isuxiz
- login: angely-dev
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/4362224?v=4
url: https://github.com/angely-dev
- login: deight93
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/37678115?u=a608798b5bd0034183a9c430ebb42fb266db86ce&v=4
@ -792,42 +688,70 @@ one_year_experts:
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/53449841?v=4
url: https://github.com/ryanisn
- login: svlandeg
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4
url: https://github.com/svlandeg
- login: alexandercronin
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/8014288?u=69580504c51a0cdd756fc47b23bb7f404bd694e7&v=4
url: https://github.com/alexandercronin
- login: aanchlia
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/2835374?u=3c3ed29aa8b09ccaf8d66def0ce82bc2f7e5aab6&v=4
url: https://github.com/aanchlia
- login: chrisK824
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/79946379?u=03d85b22d696a58a9603e55fbbbe2de6b0f4face&v=4
url: https://github.com/chrisK824
- login: omarcruzpantoja
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/15116058?u=4b64c643fad49225d854e1aaecd1ffc6f9071a1b&v=4
url: https://github.com/omarcruzpantoja
- login: ahmedabdou14
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/104530599?u=d87b866e7c1db970d6f8e8031643818349b046d5&v=4
url: https://github.com/ahmedabdou14
- login: Wyko
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/467094?v=4
url: https://github.com/Wyko
- login: ddahan
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/1933516?u=1d200a620e8d6841df017e9f2bb7efb58b580f40&v=4
url: https://github.com/ddahan
- login: Ale-Cas
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/64859146?u=d52a6ecf8d83d2927e2ae270bdfcc83495dba8c9&v=4
url: https://github.com/Ale-Cas
- login: Trolldemorted
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/10261186?v=4
url: https://github.com/Trolldemorted
- login: vtgn
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/112889052?v=4
url: https://github.com/vtgn
- login: SDAravind
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/72403396?v=4
url: https://github.com/SDAravind
- login: slafs
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/210173?v=4
url: https://github.com/slafs
- login: redb0
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/30475117?v=4
url: https://github.com/redb0
- login: pedroconceicao
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/32837064?u=5a0e6559bc391442629a28b6923790b54deb4464&v=4
url: https://github.com/pedroconceicao
- login: msukmanowsky
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/362755?u=782e6bf5b9f0356c3f74b4d894fda9f179252086&v=4
url: https://github.com/msukmanowsky
- login: rishabhc32
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/15983714?u=147776509107af8bdf099223e1840d3f40f944da&v=4
url: https://github.com/rishabhc32
- login: meower1
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/109747197?u=0a5cc2a6ae74e558f0afc2874da85132e5953d8b&v=4
url: https://github.com/meower1
- login: Trinkes
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/9466879?v=4
url: https://github.com/Trinkes
- login: Leon0824
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/1922026?v=4
url: https://github.com/Leon0824
- login: CarlosOliveira-23
- login: anantgupta129
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/102637302?u=cf350a4db956f30cbb2c27d3be0d15c282e32b14&v=4
url: https://github.com/CarlosOliveira-23
avatarUrl: https://avatars.githubusercontent.com/u/66518357?u=6e25dcd84638f17d2c6df5dc26f07fd7c6dc118e&v=4
url: https://github.com/anantgupta129
- login: nbx3
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/34649527?u=943812f69e0d40adbd3fa1c9b8ef50dd971a2a45&v=4
@ -838,16 +762,8 @@ one_year_experts:
url: https://github.com/yanggeorge
- login: XiaoXinYo
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/56395004?u=b3b7cb758997f283c271a581833e407229dab82c&v=4
avatarUrl: https://avatars.githubusercontent.com/u/56395004?u=1eebf5ce25a8067f7bfa6251a24f667be492d9d6&v=4
url: https://github.com/XiaoXinYo
- login: anantgupta129
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/66518357?u=6e25dcd84638f17d2c6df5dc26f07fd7c6dc118e&v=4
url: https://github.com/anantgupta129
- login: slafs
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/210173?v=4
url: https://github.com/slafs
- login: monchin
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/18521800?v=4
@ -860,11 +776,3 @@ one_year_experts:
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/150855?v=4
url: https://github.com/iloveitaly
- login: msukmanowsky
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/362755?u=782e6bf5b9f0356c3f74b4d894fda9f179252086&v=4
url: https://github.com/msukmanowsky
- login: shurshilov
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/11828278?u=6bcadc5ce4f2f56a514331c9f68eb987d4afe29a&v=4
url: https://github.com/shurshilov

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

2
docs/en/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">

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

@ -7,8 +7,125 @@ hide:
## Latest Changes
### Docs
* 📝 Add External Link: Taiwanese talk on FastAPI with observability . PR [#13527](https://github.com/fastapi/fastapi/pull/13527) by [@blueswen](https://github.com/blueswen).
### Translations
* 🌐 Update Chinese translation for `docs/zh/docs/tutorial/first-steps.md`. PR [#13348](https://github.com/fastapi/fastapi/pull/13348) by [@Zhongheng-Cheng](https://github.com/Zhongheng-Cheng).
### Internal
* 🔧 Clean up `docs/en/mkdocs.yml` configuration file. PR [#13542](https://github.com/fastapi/fastapi/pull/13542) by [@svlandeg](https://github.com/svlandeg).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#12986](https://github.com/fastapi/fastapi/pull/12986) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
## 0.115.12
### Fixes
* 🐛 Fix `convert_underscores=False` for header Pydantic models. PR [#13515](https://github.com/fastapi/fastapi/pull/13515) by [@tiangolo](https://github.com/tiangolo).
### Docs
* 📝 Update `docs/en/docs/tutorial/middleware.md`. PR [#13444](https://github.com/fastapi/fastapi/pull/13444) by [@Rishat-F](https://github.com/Rishat-F).
* 👥 Update FastAPI People - Experts. PR [#13493](https://github.com/fastapi/fastapi/pull/13493) by [@tiangolo](https://github.com/tiangolo).
### Translations
* 🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/metadata.md` page. PR [#13459](https://github.com/fastapi/fastapi/pull/13459) by [@valentinDruzhinin](https://github.com/valentinDruzhinin).
* 🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/response-status-code.md` page. PR [#13462](https://github.com/fastapi/fastapi/pull/13462) by [@valentinDruzhinin](https://github.com/valentinDruzhinin).
* 🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/cookie-param-models.md` page. PR [#13460](https://github.com/fastapi/fastapi/pull/13460) by [@valentinDruzhinin](https://github.com/valentinDruzhinin).
* 🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/header-param-models.md` page. PR [#13461](https://github.com/fastapi/fastapi/pull/13461) by [@valentinDruzhinin](https://github.com/valentinDruzhinin).
* 🌐 Add Japanese translation for `docs/ja/docs/virtual-environments.md`. PR [#13304](https://github.com/fastapi/fastapi/pull/13304) by [@k94-ishi](https://github.com/k94-ishi).
* 🌐 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 pydantic-ai from 0.0.15 to 0.0.30. PR [#13438](https://github.com/fastapi/fastapi/pull/13438) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ 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).
* 🌐 Add Vietnamese translation for `docs/vi/docs/environment-variables.md`. PR [#13287](https://github.com/fastapi/fastapi/pull/13287) by [@ptt3199](https://github.com/ptt3199).
@ -21,6 +138,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.

16
docs/en/docs/tutorial/header-param-models.md

@ -51,6 +51,22 @@ For example, if the client tries to send a `tool` header with a value of `plumbu
}
```
## Disable Convert Underscores
The same way as with regular header parameters, when you have underscore characters in the parameter names, they are **automatically converted to hyphens**.
For example, if you have a header parameter `save_data` in the code, the expected HTTP header will be `save-data`, and it will show up like that in the docs.
If for some reason you need to disable this automatic conversion, you can do it as well for Pydantic models for header parameters.
{* ../../docs_src/header_param_models/tutorial003_an_py310.py hl[19] *}
/// warning
Before setting `convert_underscores` to `False`, bear in mind that some HTTP proxies and servers disallow the usage of headers with underscores.
///
## Summary
You can use **Pydantic models** to declare **headers** in **FastAPI**. 😎

2
docs/en/docs/tutorial/middleware.md

@ -15,7 +15,7 @@ A "middleware" is a function that works with every **request** before it is proc
If you have dependencies with `yield`, the exit code will run *after* the middleware.
If there were any background tasks (documented later), they will run *after* all the middleware.
If there were any background tasks (covered in the [Background Tasks](background-tasks.md){.internal-link target=_blank} section, you will see it later), they will run *after* all the middleware.
///

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

76
docs/en/mkdocs.yml

@ -6,7 +6,7 @@ theme:
name: material
custom_dir: ../en/overrides
palette:
- media: "(prefers-color-scheme)"
- media: (prefers-color-scheme)
toggle:
icon: material/lightbulb-auto
name: Switch to light mode
@ -27,7 +27,6 @@ theme:
features:
- content.code.annotate
- content.code.copy
# - content.code.select
- content.footnote.tooltips
- content.tabs.link
- content.tooltips
@ -35,7 +34,6 @@ theme:
- navigation.indexes
- navigation.instant
- navigation.instant.prefetch
# - navigation.instant.preview
- navigation.instant.progress
- navigation.path
- navigation.tabs
@ -46,7 +44,6 @@ theme:
- search.share
- search.suggest
- toc.follow
icon:
repo: fontawesome/brands/github-alt
logo: img/icon-white.svg
@ -55,11 +52,7 @@ theme:
repo_name: fastapi/fastapi
repo_url: https://github.com/fastapi/fastapi
plugins:
# Material for MkDocs
search:
# Configured in mkdocs.insiders.yml
# social:
# Other plugins
search: null
macros:
include_yaml:
- external_links: ../en/data/external_links.yml
@ -103,7 +96,6 @@ plugins:
signature_crossrefs: true
show_symbol_type_heading: true
show_symbol_type_toc: true
nav:
- FastAPI: index.md
- features.md
@ -258,33 +250,27 @@ nav:
- benchmarks.md
- management.md
- release-notes.md
markdown_extensions:
# Python Markdown
abbr:
attr_list:
footnotes:
md_in_html:
tables:
abbr: null
attr_list: null
footnotes: null
md_in_html: null
tables: null
toc:
permalink: true
# Python Markdown Extensions
pymdownx.betterem:
pymdownx.caret:
pymdownx.betterem: null
pymdownx.caret: null
pymdownx.highlight:
line_spans: __span
pymdownx.inlinehilite:
pymdownx.keys:
pymdownx.mark:
pymdownx.inlinehilite: null
pymdownx.keys: null
pymdownx.mark: null
pymdownx.superfences:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format
pymdownx.tilde:
# pymdownx blocks
format: !!python/name:pymdownx.superfences.fence_code_format ''
pymdownx.tilde: null
pymdownx.blocks.admonition:
types:
- note
@ -295,17 +281,13 @@ markdown_extensions:
- tip
- hint
- warning
# Custom types
- info
- check
pymdownx.blocks.details:
pymdownx.blocks.details: null
pymdownx.blocks.tab:
alternate_style: True
# Other extensions
mdx_include:
markdown_include_variants:
alternate_style: true
mdx_include: null
markdown_include_variants: null
extra:
analytics:
provider: google
@ -313,16 +295,14 @@ extra:
feedback:
title: Was this page helpful?
ratings:
- icon: material/emoticon-happy-outline
name: This page was helpful
data: 1
note: >-
Thanks for your feedback!
- icon: material/emoticon-sad-outline
name: This page could be improved
data: 0
note: >-
Thanks for your feedback!
- icon: material/emoticon-happy-outline
name: This page was helpful
data: 1
note: Thanks for your feedback!
- icon: material/emoticon-sad-outline
name: This page could be improved
data: 0
note: Thanks for your feedback!
social:
- icon: fontawesome/brands/github-alt
link: https://github.com/fastapi/fastapi
@ -338,7 +318,6 @@ extra:
link: https://medium.com/@tiangolo
- icon: fontawesome/solid/globe
link: https://tiangolo.com
alternate:
- link: /
name: en - English
@ -390,14 +369,11 @@ extra:
name: zh-hant - 繁體中文
- link: /em/
name: 😉
extra_css:
- css/termynal.css
- css/custom.css
extra_javascript:
- js/termynal.js
- js/custom.js
hooks:
- ../../scripts/mkdocs_hooks.py

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モデルはクッキーやヘッダーの宣言にも使用できますが、その内容については後のチュートリアルで学びます。🤫
///

831
docs/ja/docs/virtual-environments.md

@ -0,0 +1,831 @@
# 仮想環境
Pythonプロジェクトの作業では、**仮想環境**(または類似の仕組み)を使用し、プロジェクトごとにインストールするパッケージを分離するべきでしょう。
/// info | 情報
もし、仮想環境の概要や作成方法、使用方法について既にご存知なら、このセクションをスキップすることができます。🤓
///
/// tip | 豆知識
**仮想環境**は、**環境変数**とは異なります。
**環境変数**は、プログラムが使用できるシステム内の変数です。
**仮想環境**は、ファイルをまとめたディレクトリのことです。
///
/// info | 情報
このページでは、**仮想環境**の使用方法と、そのはたらきについて説明します。
もし**すべてを管理するツール**(Pythonのインストールも含む)を導入する準備ができているなら、<a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a> をお試しください。
///
## プロジェクトの作成
まず、プロジェクト用のディレクトリを作成します。
私は通常 home/user ディレクトリの中に `code` というディレクトリを用意していて、プロジェクトごとに1つのディレクトリをその中に作成しています。
<div class="termy">
```console
// Go to the home directory
$ cd
// Create a directory for all your code projects
$ mkdir code
// Enter into that code directory
$ cd code
// Create a directory for this project
$ mkdir awesome-project
// Enter into that project directory
$ cd awesome-project
```
</div>
## 仮想環境の作成
Pythonプロジェクトでの**初めての**作業を開始する際には、**<abbr title="他の選択肢もありますが、これはシンプルなガイドラインです">プロジェクト内</abbr>**に仮想環境を作成してください。
/// tip | 豆知識
これを行うのは、**プロジェクトごとに1回だけ**です。作業のたびに行う必要はありません。
///
//// tab | `venv`
仮想環境を作成するには、Pythonに付属している `venv` モジュールを使用できます。
<div class="termy">
```console
$ python -m venv .venv
```
</div>
/// details | このコマンドの意味
- `python` : `python` というプログラムを呼び出します
- `-m` : モジュールをスクリプトとして呼び出します。どのモジュールを呼び出すのか、この次に指定します
- `venv` : 通常Pythonに付随してインストールされる `venv`モジュールを使用します
- `.venv` : 仮想環境を`.venv`という新しいディレクトリに作成します
///
////
//// tab | `uv`
もし <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> をインストール済みなら、仮想環境を作成するために `uv` を使うこともできます。
<div class="termy">
```console
$ uv venv
```
</div>
/// tip | 豆知識
デフォルトでは、 `uv``.venv` というディレクトリに仮想環境を作成します。
ただし、追加の引数にディレクトリ名を与えてカスタマイズすることもできます。
///
////
このコマンドは `.venv` というディレクトリに新しい仮想環境を作成します。
/// details | `.venv` またはその他の名前
仮想環境を別のディレクトリに作成することも可能ですが、 `.venv` と名付けるのが一般的な慣習です。
///
## 仮想環境の有効化
実行されるPythonコマンドやインストールされるパッケージが新しく作成した仮想環境を使用するよう、その仮想環境を有効化しましょう。
/// tip | 豆知識
そのプロジェクトの作業で**新しいターミナルセッション**を開始する際には、**毎回**有効化が必要です。
///
//// tab | Linux, macOS
<div class="termy">
```console
$ source .venv/bin/activate
```
</div>
////
//// tab | Windows PowerShell
<div class="termy">
```console
$ .venv\Scripts\Activate.ps1
```
</div>
////
//// tab | Windows Bash
もしWindowsでBashを使用している場合 (<a href="https://gitforwindows.org/" class="external-link" target="_blank">Git Bash</a>など):
<div class="termy">
```console
$ source .venv/Scripts/activate
```
</div>
////
/// tip | 豆知識
**新しいパッケージ**を仮想環境にインストールするときには、再度**有効化**してください。
こうすることで、そのパッケージがインストールした**ターミナル(<abbr title="command line interface">CLI</abbr>)プログラム**を使用する場合に、仮想環境内のものが確実に使われ、グローバル環境にインストールされている別のもの(おそらく必要なものとは異なるバージョン)を誤って使用することを防ぎます。
///
## 仮想環境が有効であることを確認する
仮想環境が有効である(前のコマンドが正常に機能した)ことを確認します。
/// tip | 豆知識
これは**任意**ですが、すべてが期待通りに機能し、意図した仮想環境を使用していることを**確認する**良い方法です。
///
//// tab | Linux, macOS, Windows Bash
<div class="termy">
```console
$ which python
/home/user/code/awesome-project/.venv/bin/python
```
</div>
`.venv/bin/python` にある `python` バイナリが、プロジェクト(この場合は `awesome-project` )内に表示されていれば、正常に動作しています 🎉。
////
//// tab | Windows PowerShell
<div class="termy">
``` console
$ Get-Command python
C:\Users\user\code\awesome-project\.venv\Scripts\python
```
</div>
`.venv\Scripts\python` にある `python` バイナリが、プロジェクト(この場合は `awesome-project` )内に表示されていれば、正常に動作しています 🎉。
////
## `pip` をアップグレードする
/// tip | 豆知識
もし <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> を使用している場合は、 `pip` の代わりに `uv` を使ってインストールを行うため、 `pip` をアップグレードする必要はありません 😎。
///
もしパッケージのインストールに `pip`(Pythonに標準で付属しています)を使用しているなら、 `pip` を最新バージョンに**アップグレード**しましょう。
パッケージのインストール中に発生する想定外のエラーの多くは、最初に `pip` をアップグレードしておくだけで解決されます。
/// tip | 豆知識
通常、これは仮想環境を作成した直後に**一度だけ**実行します。
///
仮想環境が有効であることを(上で説明したコマンドで)確認し、アップグレードを実行しましょう:
<div class="termy">
```console
$ python -m pip install --upgrade pip
---> 100%
```
</div>
## `.gitignore` を追加する
**Git**を使用している場合(使用するべきでしょう)、 `.gitignore` ファイルを追加して、 `.venv` 内のあらゆるファイルをGitの管理対象から除外します。
/// tip | 豆知識
もし <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> を使用して仮想環境を作成した場合、すでにこの作業は済んでいるので、この手順をスキップできます 😎。
///
/// tip | 豆知識
これも、仮想環境を作成した直後に**一度だけ**実行します。
///
<div class="termy">
```console
$ echo "*" > .venv/.gitignore
```
</div>
/// details | このコマンドの意味
- `echo "*"` : ターミナルに `*` というテキストを「表示」しようとします。(次の部分によってその動作が少し変わります)
- `>` : `>` の左側のコマンドがターミナルに表示しようとする内容を、ターミナルには表示せず、 `>` の右側のファイルに書き込みます。
- `.gitignore` : `*` を書き込むファイル名。
ここで、Gitにおける `*` は「すべて」を意味するので、このコマンドによって `.venv` ディレクトリ内のすべてがGitに無視されるようになります。
このコマンドは以下のテキストを持つ `.gitignore` ファイルを作成します:
```gitignore
*
```
///
## パッケージのインストール
仮想環境を有効化した後、その中でパッケージをインストールできます。
/// tip | 豆知識
プロジェクトに必要なパッケージをインストールまたはアップグレードする場合、これを**一度**実行します。
もし新しいパッケージを追加したり、バージョンをアップグレードする必要がある場合は、もう**一度この手順を繰り返し**ます。
///
### パッケージを直接インストールする
急いでいて、プロジェクトのパッケージ要件を宣言するファイルを使いたくない場合、パッケージを直接インストールできます。
/// tip | 豆知識
プログラムが必要とするパッケージとバージョンをファイル(例えば `requirements.txt``pyproject.toml` )に記載しておくのは、(とても)良い考えです。
///
//// tab | `pip`
<div class="termy">
```console
$ pip install "fastapi[standard]"
---> 100%
```
</div>
////
//// tab | `uv`
もし <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> を使用できるなら:
<div class="termy">
```console
$ uv pip install "fastapi[standard]"
---> 100%
```
</div>
////
### `requirements.txt` からインストールする
もし `requirements.txt` があるなら、パッケージのインストールに使用できます。
//// tab | `pip`
<div class="termy">
```console
$ pip install -r requirements.txt
---> 100%
```
</div>
////
//// tab | `uv`
もし <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> を使用できるなら:
<div class="termy">
```console
$ uv pip install -r requirements.txt
---> 100%
```
</div>
////
/// details | `requirements.txt`
パッケージが記載された `requirements.txt` は以下のようになっています:
```requirements.txt
fastapi[standard]==0.113.0
pydantic==2.8.0
```
///
## プログラムを実行する
仮想環境を有効化した後、プログラムを実行できます。この際、仮想環境内のPythonと、そこにインストールしたパッケージが使用されます。
<div class="termy">
```console
$ python main.py
Hello World
```
</div>
## エディタの設定
プロジェクトではおそらくエディタを使用するでしょう。コード補完やインラインエラーの表示ができるように、作成した仮想環境をエディタでも使えるよう設定してください。(多くの場合、自動検出されます)
設定例:
* <a href="https://code.visualstudio.com/docs/python/environments#_select-and-activate-an-environment" class="external-link" target="_blank">VS Code</a>
* <a href="https://www.jetbrains.com/help/pycharm/creating-virtual-environment.html" class="external-link" target="_blank">PyCharm</a>
/// tip | 豆知識
この設定は通常、仮想環境を作成した際に**一度だけ**行います。
///
## 仮想環境の無効化
プロジェクトの作業が終了したら、その仮想環境を**無効化**できます。
<div class="termy">
```console
$ deactivate
```
</div>
これにより、 `python` コマンドを実行しても、そのプロジェクト用(のパッケージがインストールされた)仮想環境から `python` プログラムを呼び出そうとはしなくなります。
## 作業準備完了
ここまでで、プロジェクトの作業を始める準備が整いました。
/// tip | 豆知識
上記の内容を理解したいですか?
もしそうなら、以下を読み進めてください。👇🤓
///
## なぜ仮想環境?
FastAPIを使った作業をするには、 [Python](https://www.python.org/) のインストールが必要です。
それから、FastAPIや、使用したいその他の**パッケージ**を**インストール**する必要があります。
パッケージをインストールするには、通常、Python に付属する `pip` コマンド (または同様の代替コマンド) を使用します。
ただし、`pip` を直接使用すると、パッケージは**グローバルなPython環境**(OS全体にインストールされたPython環境)にインストールされます。
### 問題点
では、グローバルPython環境にパッケージをインストールすることの問題点は何でしょうか?
ある時点で、あなたは**異なるパッケージ**に依存する多くのプログラムを書くことになるでしょう。そして、これらの中には同じパッケージの**異なるバージョン**に依存するものも出てくるでしょう。😱
例えば、 `philosophers-stone` (賢者の石)というプロジェクトを作成するとします。このプログラムは **`harry` (ハリー)というパッケージのバージョン `1`**に依存しています。そのため、 `harry` (ハリー)をインストールする必要があります。
```mermaid
flowchart LR
stone(philosophers-stone) -->|requires| harry-1[harry v1]
```
それから、 `prisoner-of-azkaban` (アズカバンの囚人)という別のプロジェクトを作成したとします。このプロジェクトも `harry` (ハリー)に依存していますが、**`harry` (ハリー)のバージョン `3`**が必要です。
```mermaid
flowchart LR
azkaban(prisoner-of-azkaban) --> |requires| harry-3[harry v3]
```
しかし、ここで問題になるのは、もしローカルの**仮想環境**ではなくグローバル(環境)にパッケージをインストールするなら、 `harry` (ハリー)のどのバージョンをインストールするか選ばないといけないことです。
例えば、 `philosophers-stone` (賢者の石)を実行するには、まず `harry` (ハリー)のバージョン `1` をインストールする必要があります:
<div class="termy">
```console
$ pip install "harry==1"
```
</div>
これにより、`harry` (ハリー)バージョン1がグローバルなPython環境にインストールされます。
```mermaid
flowchart LR
subgraph global[global env]
harry-1[harry v1]
end
subgraph stone-project[philosophers-stone project]
stone(philosophers-stone) -->|requires| harry-1
end
```
しかし、 `prisoner-of-azkaban` (アズカバンの囚人)を実行したい場合は、`harry` (ハリー)のバージョン `1` をアンインストールし、`harry` (ハリー)のバージョン `3` をインストールし直す必要があります。(あるいは、単に`harry` (ハリー)のバージョン `3` をインストールすることで、自動的にバージョン `1` がアンインストールされます)
<div class="termy">
```console
$ pip install "harry==3"
```
</div>
このようにして、グローバル環境への `harry` (ハリー)のバージョン `3` のインストールが完了します。
それから、 `philosophers-stone` (賢者の石)を再び実行しようとすると、このプログラムは `harry` (ハリー)のバージョン `1` が必要なため、**動作しなくなる**可能性があります。
```mermaid
flowchart LR
subgraph global[global env]
harry-1[<strike>harry v1</strike>]
style harry-1 fill:#ccc,stroke-dasharray: 5 5
harry-3[harry v3]
end
subgraph stone-project[philosophers-stone project]
stone(philosophers-stone) -.-x|⛔️| harry-1
end
subgraph azkaban-project[prisoner-of-azkaban project]
azkaban(prisoner-of-azkaban) --> |requires| harry-3
end
```
/// tip | 豆知識
Pythonのパッケージでは、**新しいバージョン**で**互換性を損なう変更を避ける**よう努めるのが一般的ですが、それでも注意が必要です。すべてが正常に動作することをテストで確認してから、意図的に指定して新しいバージョンをインストールするのが良いでしょう。
///
あなたのすべての**プロジェクトが依存している**、**多数の**他の**パッケージ**が上記の問題を抱えていると想像してください。これは管理が非常に困難です。そして、**互換性のないバージョン**のパッケージを使ってプロジェクトを実行し、なぜ動作しないのか分からなくなるでしょう。
また、使用しているOS(Linux、Windows、macOS など)によっては、Pythonがすでにインストールされていることがあります。この場合、特定のバージョンのパッケージが**OSの動作に必要である**ことがあります。グローバル環境にパッケージをインストールすると、OSに付属するプログラムを**壊してしまう**可能性があります。
## パッケージのインストール先
Pythonをインストールしたとき、ファイルを含んだいくつかのディレクトリが作成されます。
これらの中には、インストールされたパッケージを保存するためのものもあります。
以下のコマンドを実行したとき:
<div class="termy">
```console
// Don't run this now, it's just an example 🤓
$ pip install "fastapi[standard]"
---> 100%
```
</div>
FastAPIのコードを含む圧縮ファイルが、通常は [PyPI](https://pypi.org/project/fastapi/) からダウンロードされます。
また、FastAPIが依存する他のパッケージも**ダウンロード**されます。
それから、これらのファイルは**解凍**され、コンピュータのあるディレクトリに配置されます。
デフォルトでは、これらのファイルはPythonのインストール時に作成されるディレクトリ、つまり**グローバル環境**に配置されます。
## 仮想環境とは
すべてのパッケージをグローバル環境に配置することによって生じる問題の解決策は、作業する**プロジェクトごとの仮想環境**を使用することです。
仮想環境は**ディレクトリ**であり、グローバル環境と非常に似ていて、一つのプロジェクトで使う特定のパッケージ群をインストールできる場所です。
このようにして、それぞれのプロジェクトが独自の仮想環境(`.venv` ディレクトリ)に独自のパッケージ群を持つことができます。
```mermaid
flowchart TB
subgraph stone-project[philosophers-stone project]
stone(philosophers-stone) --->|requires| harry-1
subgraph venv1[.venv]
harry-1[harry v1]
end
end
subgraph azkaban-project[prisoner-of-azkaban project]
azkaban(prisoner-of-azkaban) --->|requires| harry-3
subgraph venv2[.venv]
harry-3[harry v3]
end
end
stone-project ~~~ azkaban-project
```
## 仮想環境の有効化とは
仮想環境を有効にしたとき、例えば次のコマンドを実行した場合を考えます:
//// tab | Linux, macOS
<div class="termy">
```console
$ source .venv/bin/activate
```
</div>
////
//// tab | Windows PowerShell
<div class="termy">
```console
$ .venv\Scripts\Activate.ps1
```
</div>
////
//// tab | Windows Bash
あるいは、WindowsでBashを使用している場合 (<a href="https://gitforwindows.org/" class="external-link" target="_blank">Git Bash</a>など):
<div class="termy">
```console
$ source .venv/Scripts/activate
```
</div>
////
これによって、いくつかの [環境変数](environment-variables.md){.internal-link target=_blank} が作成・修正され、次に実行されるコマンドで使用できるようになります。
これらの環境変数のひとつに、 `PATH` 変数があります。
/// tip | 豆知識
`PATH` 変数についての詳細は [環境変数](environment-variables.md#path環境変数){.internal-link target=_blank} を参照してください。
///
仮想環境を有効にすると、その仮想環境のパス `.venv/bin` (LinuxとmacOS)、あるいは `.venv\Scripts` (Windows)が `PATH` 変数に追加されます。
その環境を有効にする前の `PATH` 変数が次のようになっているとします。
//// tab | Linux, macOS
```plaintext
/usr/bin:/bin:/usr/sbin:/sbin
```
これは、OSが以下のディレクトリ中でプログラムを探すことを意味します:
* `/usr/bin`
* `/bin`
* `/usr/sbin`
* `/sbin`
////
//// tab | Windows
```plaintext
C:\Windows\System32
```
これは、OSが以下のディレクトリ中でプログラムを探すことを意味します:
* `C:\Windows\System32`
////
仮想環境を有効にすると、 `PATH` 変数は次のようになります。
//// tab | Linux, macOS
```plaintext
/home/user/code/awesome-project/.venv/bin:/usr/bin:/bin:/usr/sbin:/sbin
```
これは、OSが他のディレクトリを探すより前に、最初に以下のディレクトリ中でプログラムを探し始めることを意味します:
```plaintext
/home/user/code/awesome-project/.venv/bin
```
そのため、ターミナルで `python` と入力した際に、OSはPythonプログラムを以下のパスで発見し、使用します。
```plaintext
/home/user/code/awesome-project/.venv/bin/python
```
////
//// tab | Windows
```plaintext
C:\Users\user\code\awesome-project\.venv\Scripts;C:\Windows\System32
```
これは、OSが他のディレクトリを探すより前に、最初に以下のディレクトリ中でプログラムを探し始めることを意味します:
```plaintext
C:\Users\user\code\awesome-project\.venv\Scripts
```
そのため、ターミナルで `python` と入力した際に、OSはPythonプログラムを以下のパスで発見し、使用します。
```plaintext
C:\Users\user\code\awesome-project\.venv\Scripts\python
```
////
重要な点は、仮想環境のパスを `PATH` 変数の**先頭**に配置することです。OSは利用可能な他のPythonを見つけるより**前に**、この仮想環境のPythonを見つけるようになります。このようにして、 `python` を実行したときに、他の `python` (例えばグローバル環境の `python` )ではなく、**その仮想環境の**Pythonを使用するようになります。
仮想環境を有効にして変更されることは他にもありますが、これが最も重要な変更のひとつです。
## 仮想環境の確認
仮想環境が有効かどうか、例えば次のように確認できます。:
//// tab | Linux, macOS, Windows Bash
<div class="termy">
```console
$ which python
/home/user/code/awesome-project/.venv/bin/python
```
</div>
////
//// tab | Windows PowerShell
<div class="termy">
```console
$ Get-Command python
C:\Users\user\code\awesome-project\.venv\Scripts\python
```
</div>
////
これは、使用される `python` プログラムが**その仮想環境の**ものであることを意味します。
LinuxやmacOSでは `which` を、Windows PowerShellでは `Get-Command` を使用します。
このコマンドの動作は、 `PATH`変数に設定された**それぞれのパスを順に**確認していき、呼ばれている `python` プログラムを探します。そして、見つかり次第そのプログラムへの**パスを表示します**。
最も重要なことは、 `python` が呼ばれたときに、まさにこのコマンドで確認した "`python`" が実行されることです。
こうして、自分が想定通りの仮想環境にいるかを確認できます。
/// tip | 豆知識
ある仮想環境を有効にし、そのPythonを使用したまま**他のプロジェクトに移動して**しまうことは簡単に起こり得ます。
そして、その第二のプロジェクトは動作しないでしょう。なぜなら別のプロジェクトの仮想環境の**誤ったPython**を使用しているからです。
そのため、どの `python` が使用されているのか確認できることは役立ちます。🤓
///
## なぜ仮想環境を無効化するのか
例えば、`philosophers-stone` (賢者の石)というプロジェクトで作業をしていて、**その仮想環境を有効にし**、必要なパッケージをインストールしてその環境内で作業を進めているとします。
それから、**別のプロジェクト**、 `prisoner-of-azkaban` (アズカバンの囚人)に取り掛かろうとします。
そのプロジェクトディレクトリへ移動します:
<div class="termy">
```console
$ cd ~/code/prisoner-of-azkaban
```
</div>
もし `philosophers-stone` (賢者の石)の仮想環境を無効化していないと、`python` を実行したとき、 ターミナルは `philosophers-stone` (賢者の石)のPythonを使用しようとします。
<div class="termy">
```console
$ cd ~/code/prisoner-of-azkaban
$ python main.py
// Error importing sirius, it's not installed 😱
Traceback (most recent call last):
File "main.py", line 1, in <module>
import sirius
```
</div>
しかし、その仮想環境を無効化し、 `prisoner-of-azkaban` (アズカバンの囚人)のための新しい仮想環境を有効にすれば、 `python` を実行したときに `prisoner-of-azkaban` (アズカバンの囚人)の仮想環境の Python が使用されるようになります。
<div class="termy">
```console
$ cd ~/code/prisoner-of-azkaban
// You don't need to be in the old directory to deactivate, you can do it wherever you are, even after going to the other project 😎
$ deactivate
// Activate the virtual environment in prisoner-of-azkaban/.venv 🚀
$ source .venv/bin/activate
// Now when you run python, it will find the package sirius installed in this virtual environment ✨
$ python main.py
I solemnly swear 🐺
```
</div>
## 代替手段
これは、あらゆる仕組みを**根本から**学ぶためのシンプルな入門ガイドです。
仮想環境、パッケージの依存関係(requirements)、プロジェクトの管理には、多くの**代替手段**があります。
準備が整い、パッケージの依存関係、仮想環境など**プロジェクト全体の管理**ツールを使いたいと考えたら、<a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a> を試してみることをおすすめします。
`uv` では以下のような多くのことができます:
* 異なるバージョンも含めた**Python のインストール**
* プロジェクトごとの**仮想環境**の管理
* **パッケージ**のインストール
* プロジェクトのパッケージの**依存関係やバージョン**の管理
* パッケージとそのバージョンの、依存関係を含めた**厳密な**組み合わせを保持し、これによって、本番環境で、開発環境と全く同じようにプロジェクトを実行できる(これは**locking**と呼ばれます)
* その他のさまざまな機能
## まとめ
ここまで読みすべて理解したなら、世間の多くの開発者と比べて、仮想環境について**あなたはより多くのことを知っています**。🤓
これらの詳細を知ることは、将来、複雑に見える何かのデバッグにきっと役立つでしょう。しかし、その頃には、あなたは**そのすべての動作を根本から**理解しているでしょう。😎

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

275
docs/ko/docs/tutorial/dependencies/dependencies-with-yield.md

@ -0,0 +1,275 @@
# yield를 사용하는 의존성
FastAPI는 <abbr title='때로는 "종료 코드", "정리 코드", "종료 처리 코드", "닫기 코드", "컨텍스트 관리자 종료 코드" 등으로도 불립니다'>작업 완료 후 추가 단계를 수행하는</abbr> 의존성을 지원합니다.
이를 구현하려면 `return` 대신 `yield`를 사용하고, 추가로 실행할 단계 (코드)를 그 뒤에 작성하세요.
/// tip | 팁
각 의존성마다 `yield`는 한 번만 사용해야 합니다.
///
/// note | 기술 세부사항
다음과 함께 사용할 수 있는 모든 함수:
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager" class="external-link" target="_blank">`@contextlib.contextmanager`</a> 또는
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager" class="external-link" target="_blank">`@contextlib.asynccontextmanager`</a>
는 **FastAPI**의 의존성으로 사용할 수 있습니다.
사실, FastAPI는 내부적으로 이 두 데코레이터를 사용합니다.
///
## `yield`를 사용하는 데이터베이스 의존성
예를 들어, 이 기능을 사용하면 데이터베이스 세션을 생성하고 작업이 끝난 후에 세션을 종료할 수 있습니다.
응답을 생성하기 전에는 `yield`문을 포함하여 그 이전의 코드만이 실행됩니다:
{* ../../docs_src/dependencies/tutorial007.py hl[2:4] *}
yield된 값은 *경로 작업* 및 다른 의존성들에 주입되는 값 입니다:
{* ../../docs_src/dependencies/tutorial007.py hl[4] *}
`yield`문 다음의 코드는 응답을 생성한 후 보내기 전에 실행됩니다:
{* ../../docs_src/dependencies/tutorial007.py hl[5:6] *}
/// tip | 팁
`async` 함수와 일반 함수 모두 사용할 수 있습니다.
**FastAPI**는 일반 의존성과 마찬가지로 각각의 함수를 올바르게 처리할 것입니다.
///
## `yield``try`를 사용하는 의존성
`yield`를 사용하는 의존성에서 `try` 블록을 사용한다면, 의존성을 사용하는 도중 발생한 모든 예외를 받을 수 있습니다.
예를 들어, 다른 의존성이나 *경로 작업*의 중간에 데이터베이스 트랜잭션 "롤백"이 발생하거나 다른 오류가 발생한다면, 해당 예외를 의존성에서 받을 수 있습니다.
따라서, 의존성 내에서 `except SomeException`을 사용하여 특정 예외를 처리할 수 있습니다.
마찬가지로, `finally`를 사용하여 예외 발생 여부와 관계 없이 종료 단계까 실행되도록 할 수 있습니다.
{* ../../docs_src/dependencies/tutorial007.py hl[3,5] *}
## `yield`를 사용하는 하위 의존성
모든 크기와 형태의 하위 의존성과 하위 의존성의 "트리"도 가질 수 있으며, 이들 모두가 `yield`를 사용할 수 있습니다.
**FastAPI**는 `yield`를 사용하는 각 의존성의 "종료 코드"가 올바른 순서로 실행되도록 보장합니다.
예를 들어, `dependency_c``dependency_b`에 의존할 수 있고, `dependency_b``dependency_a`에 의존할 수 있습니다.
{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[6,14,22] *}
이들 모두는 `yield`를 사용할 수 있습니다.
이 경우 `dependency_c`는 종료 코드를 실행하기 위해, `dependency_b`의 값 (여기서는 `dep_b`로 명명)이 여전히 사용 가능해야 합니다.
그리고, `dependency_b`는 종료 코드를 위해 `dependency_a`의 값 (여기서는 `dep_a`로 명명) 이 사용 가능해야 합니다.
{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[18:19,26:27] *}
같은 방식으로, `yield`를 사용하는 의존성과 `return`을 사용하는 의존성을 함께 사용할 수 있으며, 이들 중 일부가 다른 것들에 의존할 수 있습니다.
그리고 `yield`를 사용하는 다른 여러 의존성을 필요로 하는 단일 의존성을 가질 수도 있습니다.
원하는 의존성을 원하는 대로 조합할 수 있습니다.
**FastAPI**는 모든 것이 올바른 순서로 실행되도록 보장합니다.
/// note | 기술 세부사항
파이썬의 <a href=“https://docs.python.org/3/library/contextlib.html” class=“external-link” target=“_blank”>Context Managers</a> 덕분에 이 기능이 작동합니다.
**FastAPI**는 이를 내부적으로 컨텍스트 관리자를 사용하여 구현합니다.
///
## `yield``HTTPException`를 사용하는 의존성
`yield``try` 블록이 있는 의존성을 사용하여 예외를 처리할 수 있다는 것을 알게 되었습니다.
같은 방식으로, `yield` 이후의 종료 코드에서 `HTTPException`이나 유사한 예외를 발생시킬 수 있습니다.
/// tip | 팁
이는 다소 고급 기술이며, 대부분의 경우 경로 연산 함수 등 나머지 애플리케이션 코드 내부에서 예외 (`HTTPException` 포함)를 발생시킬 수 있으므로 실제로는 필요하지 않을 것입니다.
하지만 필요한 경우 사용할 수 있습니다. 🤓
///
{* ../../docs_src/dependencies/tutorial008b_an_py39.py hl[18:22,31] *}
예외를 처리하고(또는 추가로 다른 `HTTPException`을 발생시키기 위해) 사용할 수 있는 또 다른 방법은 [사용자 정의 예외 처리기](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}를 생성하는 것 입니다.
## `yield``except`를 사용하는 의존성
`yield`를 사용하는 의존성에서 `except`를 사용하여 예외를 포착하고 예외를 다시 발생시키지 않거나 (또는 새 예외를 발생시키지 않으면), FastAPI는 해당 예외가 발생했는지 알 수 없습니다. 이는 일반적인 Python 방식과 동일합니다:
{* ../../docs_src/dependencies/tutorial008c_an_py39.py hl[15:16] *}
이 경우, `HTTPException`이나 유사한 예외를 발생시키지 않기 때문에 클라이언트는 HTTP 500 Internal Server Error 응답을 보게 되지만, 서버는 어떤 오류가 발생했는지에 대한 **로그**나 다른 표시를 전혀 가지지 않게 됩니다. 😱
### `yield``except`를 사용하는 의존성에서 항상 `raise` 하기
`yield`가 있는 의존성에서 예외를 잡았을 때는 `HTTPException`이나 유사한 예외를 새로 발생시키지 않는 한, 반드시 원래의 예외를 다시 발생시켜야 합니다.
`raise`를 사용하여 동일한 예외를 다시 발생시킬 수 있습니다:
{* ../../docs_src/dependencies/tutorial008d_an_py39.py hl[17] *}
이제 클라이언트는 동일한 *HTTP 500 Internal Server Error* 오류 응답을 받게 되지만, 서버 로그에는 사용자 정의 예외인 `InternalError"가 기록됩니다. 😎
## `yield`를 사용하는 의존성의 실행 순서
실행 순서는 아래 다이어그램과 거의 비슷합니다. 시간은 위에서 아래로 흐릅니다. 그리고 각 열은 상호 작용하거나 코드를 실행하는 부분 중 하나입니다.
```mermaid
sequenceDiagram
participant client as Client
participant handler as Exception handler
participant dep as Dep with yield
participant operation as Path Operation
participant tasks as Background tasks
Note over client,operation: Can raise exceptions, including HTTPException
client ->> dep: Start request
Note over dep: Run code up to yield
opt raise Exception
dep -->> handler: Raise Exception
handler -->> client: HTTP error response
end
dep ->> operation: Run dependency, e.g. DB session
opt raise
operation -->> dep: Raise Exception (e.g. HTTPException)
opt handle
dep -->> dep: Can catch exception, raise a new HTTPException, raise other exception
end
handler -->> client: HTTP error response
end
operation ->> client: Return response to client
Note over client,operation: Response is already sent, can't change it anymore
opt Tasks
operation -->> tasks: Send background tasks
end
opt Raise other exception
tasks -->> tasks: Handle exceptions in the background task code
end
```
/// info | 정보
클라이언트에 **하나의 응답** 만 전송됩니다. 이는 오류 응답 중 하나일 수도 있고,*경로 작업*에서 생성된 응답일 수도 있습니다.
이러한 응답 중 하나가 전송된 후에는 다른 응답을 보낼 수 없습니다.
///
/// tip | 팁
이 다이어그램은 `HTTPException`을 보여주지만, `yield`를 사용하는 의존성에서 처리한 예외나 [사용자 정의 예외처리기](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.를 사용하여 처리한 다른 예외도 발생시킬 수 있습니다.
어떤 예외가 발생하든, `HTTPException`을 포함하여 yield를 사용하는 의존성으로 전달됩니다. 대부분의 경우 예외를 다시 발생시키거나 새로운 예외를 발생시켜야 합니다.
///
## `yield`, `HTTPException`, `except` 및 백그라운드 작업을 사용하는 의존성
/// warning | 경고
이러한 기술적 세부 사항은 대부분 필요하지 않으므로 이 섹션을 건너뛰고 아래에서 계속 진행해도 됩니다.
이러한 세부 정보는 주로 FastAPI 0.106.0 이전 버전에서 `yield`가 있는 의존성의 리소스를 백그라운드 작업에서 사용했던 경우메 유용합니다.
///
### `yield``except`를 사용하는 의존성, 기술 세부사항
FastAPI 0.110.0 이전에는 `yield`가 포함된 의존성을 사용한 후 해당 의존성에서 `except`가 포함된 예외를 캡처하고 다시 예외를 발생시키지 않으면 예외가 자동으로 예외 핸들러 또는 내부 서버 오류 핸들러로 발생/전달되었습니다.
이는 처리기 없이 전달된 예외(내부 서버 오류)에서 처리되지 않은 메모리 소비를 수정하고 일반 파이썬 코드의 동작과 일치하도록 하기 위해 0.110.0 버전에서 변경되었습니다.
### 백그라운드 작업과 `yield`를 사용하는 의존성, 기술 세부사항
FastAPI 0.106.0 이전에는 `yield` 이후에 예외를 발생시키는 것이 불가능했습니다. `yield`가 있는 의존성 종료 코드는 응답이 전송된 이후에 실행되었기 때문에, [예외 처리기](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}가 이미 실행된 상태였습니다.
이는 주로 백그라운드 작업 내에서 의존성에서 "yield된" 동일한 객체를 사용할 수 있도록 하기 위해 이런 방식으로 설계되었습니다. 종료 코드는 백그라운드 작업이 완료된 후에 실행되었기 때문입니다
하지만 이렇게 하면 리소스를 불필요하게 양보한 의존성(예: 데이터베이스 연결)에서 보유하면서 응답이 네트워크를 통해 이동할 때까지 기다리는 것을 의미하기 때문에 FastAPI 0.106.0에서 변경되었습니다.
/// tip | 팁
또한 백그라운드 작업은 일반적으로 자체 리소스(예: 자체 데이터베이스 연결)를 사용하여 별도로 처리해야 하는 독립적인 로직 집합입니다.
따라서 이렇게 하면 코드가 더 깔끔해집니다.
///
만약 이전에 이러한 동작에 의존했다면, 이제는 백그라운드 작업 내부에서 백그라운드 작업을 위한 리소스를 생성하고, `yield`가 있는 의존성의 리소스에 의존하지 않는 데이터만 내부적으로 사용해야합니다.
예를 들어, 동일한 데이터베이스 세션을 사용하는 대신, 백그라운드 작업 내부에서 새로운 데이터베이스 세션을 생성하고 이 새로운 세션을 사용하여 데이터베이스에서 객체를 가져와야 합니다. 그리고 데이터베이스 객체를 백그라운드 작업 함수의 매개변수로 직접 전달하는 대신, 해당 객체의 ID를 전달한 다음 백그라운드 작업 함수 내부에서 객체를 다시 가져와야 합니다
## 컨텍스트 관리자
### "컨텍스트 관리자"란?
"컨텍스트 관리자"는 Python에서 `with` 문에서 사용할 수 있는 모든 객체를 의미합니다.
예를 들어, <a href="https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files" class="external-link" target="_blank"> `with`를 사용하여 파일을 읽을 수 있습니다</a>:
```Python
with open("./somefile.txt") as f:
contents = f.read()
print(contents)
```
내부적으로 `open("./somefile.txt")` 는 "컨텍스트 관리자(Context Manager)"라고 불리는 객체를 생성합니다.
`with` 블록이 끝나면, 예외가 발생했더라도 파일을 닫도록 보장합니다.
`yield`가 있는 의존성을 생성하면 **FastAPI**는 내부적으로 이를 위한 컨텍스트 매니저를 생성하고 다른 관련 도구들과 결합합니다.
### `yield`를 사용하는 의존성에서 컨텍스트 관리자 사용하기
/// warning | 경고
이것은 어느 정도 "고급" 개념입니다.
**FastAPI**를 처음 시작하는 경우 지금은 이 부분을 건너뛰어도 좋습니다.
///
Python에서는 다음을 통해 컨텍스트 관리자를 생성할 수 있습니다. <a href="https://docs.python.org/3/reference/datamodel.html#context-managers" class="external-link" target="_blank"> 두 가지 메서드가 있는 클래스를 생성합니다: `__enter__()` and `__exit__()`</a>.
**FastAPI**의 `yield`가 있는 의존성 내에서
`with` 또는 `async with`문을 사용하여 이들을 활용할 수 있습니다:
{* ../../docs_src/dependencies/tutorial010.py hl[1:9,13] *}
/// tip | 팁
컨텍스트 관리자를 생성하는 또 다른 방법은 다음과 같습니다:
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager" class="external-link" target="_blank">`@contextlib.contextmanager`</a> 또는
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager" class="external-link" target="_blank">`@contextlib.asynccontextmanager`</a>
이들은 단일 `yield`가 있는 함수를 꾸미는 데 사용합니다.
이것이 **FastAPI**가 `yield`가 있는 의존성을 위해 내부적으로 사용하는 방식입니다.
하지만 FastAPI 의존성에는 이러한 데코레이터를 사용할 필요가 없습니다(그리고 사용해서도 안됩니다).
FastAPI가 내부적으로 이를 처리해 줄 것입니다.
///

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, зберігаючи при цьому код простим, коротким та елегантним.
А також отримуєте всі переваги:
* Підтримка в редакторі (автодоповнення всюди!)
* Конвертація даних (парсинг/сериалізація)
* Валідація даних
* Документація схем
* Автоматичне створення документації

76
docs/uk/docs/tutorial/cookie-param-models.md

@ -0,0 +1,76 @@
# Моделі для Cookie-параметрів
Якщо у Вас є група **cookies** параметрів, які пов'язані між собою, Ви можете створити **Pydantic-модель**, щоб оголосити їх. 🍪
Це дозволить Вам повторно **використовувати модель** у **різних місцях**, а також оголосити валідацію та метадані для всіх параметрів одночасно. 😎
/// note | Нотатки
Це підтримується з версії FastAPI `0.115.0`. 🤓
///
/// tip | Порада
Ця ж техніка застосовується до `Query`, `Cookie`, та `Header`. 😎
///
## Cookie з Pydantic-моделлю
Оголосіть **cookie-параметри**, які Вам потрібні, у **Pydantic-моделі**, а потім оголосіть параметр як `Cookie`:
{* ../../docs_src/cookie_param_models/tutorial001_an_py310.py hl[9:12,16] *}
**FastAPI** буде **витягувати** дані для **кожного поля** з **cookie** параметрів, отриманих у запиті, і передавати Вам Pydantic-модель, яку Ви визначили.
## Перевірка у документації
Ви можете побачити визначені cookie в інтерфейсі документації за адресою `/docs`:
<div class="screenshot">
<img src="/img/tutorial/cookie-param-models/image01.png">
</div>
/// info | Інформація
Майте на увазі, що оскільки **браузери обробляють cookie** особливим чином і "за лаштунками", вони **не** дозволяють **JavaScript** легко з ними працювати.
Якщо Ви зайдете до **інтерфейсу документації API** за адресою `/docs`, Ви зможете побачити **документацію** для cookie у Ваших **операціях шляху**.
Але навіть якщо Ви заповните дані й натиснете "Execute", оскільки інтерфейс документації працює з **JavaScript**, cookie не будуть відправлені, і Ви побачите **помилку**, ніби Ви не ввели жодних значень.
///
## Заборона додаткових cookie
У деяких спеціальних випадках (ймовірно, не дуже поширених) Ви можете захотіти **обмежити** список cookie, які хочете отримувати.
Ваша API тепер має можливість контролювати власну <abbr title="Це жарт, якщо що. Це не має нічого спільного зі згодою на використання cookie, але це кумедно, що навіть API тепер може відхиляти бідні cookie. Ловіть печиво. 🍪">згоду на cookie</abbr>. 🤪🍪
Ви можете використовувати налаштування моделі Pydantic, щоб `заборонити` будь-які `додаткові` поля:
{* ../../docs_src/cookie_param_models/tutorial002_an_py39.py hl[10] *}
Якщо клієнт спробує надіслати якісь **додаткові cookie**, він отримає відповідь з **помилкою**.
Бідні банери cookie, які так старанно намагаються отримати Вашу згоду, щоб <abbr title="Це ще один жарт. Не звертайте уваги. Візьміть каву для свого печива. ☕">API її відхилила</abbr>. 🍪
Наприклад, якщо клієнт спробує надіслати cookie `santa_tracker` зі значенням `good-list-please`, він отримає відповідь з помилкою, яка повідомить, що <abbr title="Санта не схвалює відсутність cookie. 🎅 Гаразд, більше жартів не буде.">cookie `santa_tracker` не дозволено</abbr>:
```json
{
"detail": [
{
"type": "extra_forbidden",
"loc": ["cookie", "santa_tracker"],
"msg": "Extra inputs are not permitted",
"input": "good-list-please",
}
]
}
```
## Підсумок
Ви можете використовувати **Pydantic-моделі** для оголошення <abbr title="Отримайте останнє печиво перед тим, як піти. 🍪">cookie</abbr> у FastAPI. 😎

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

58
docs/uk/docs/tutorial/header-param-models.md

@ -0,0 +1,58 @@
# Моделі Параметрів Заголовків
Якщо у Вас є група пов’язаних параметрів заголовків, Ви можете створити **Pydantic модель** для їх оголошення.
Це дозволить Вам повторно **використовувати модель** в **різних місцях**, а також оголосити валідації та метадані для всіх параметрів одночасно. 😎
/// note | Нотатки
Ця можливість підтримується починаючи з версії FastAPI `0.115.0`. 🤓
///
## Параметри Заголовків з Використанням Pydantic Model
Оголосіть потрібні **параметри заголовків** у **Pydantic моделі**, а потім оголосіть параметр як `Header`:
{* ../../docs_src/header_param_models/tutorial001_an_py310.py hl[9:14,18] *}
FastAPI буде витягувати дані для кожного поля з заголовків у запиті та передавати їх у створену Вами Pydantic модель.
**FastAPI** буде **витягувати** дані для **кожного поля** з **заголовків** у запиті та передавати їх у створену Вами Pydantic модель.
## Перевірка в Документації
Ви можете побачити необхідні заголовки в інтерфейсі документації за адресою `/docs`:
<div class="screenshot">
<img src="/img/tutorial/header-param-models/image01.png">
</div>
## Заборона Додаткових Заголовків
У деяких особливих випадках (ймовірно, не дуже поширених) Ви можете захотіти **обмежити** заголовки, які хочете отримати.
Ви можете використати конфігурацію моделі Pydantic, щоб `заборонити` будь-які `додаткові` поля:
{* ../../docs_src/header_param_models/tutorial002_an_py310.py hl[10] *}
Якщо клієнт спробує надіслати **додаткові заголовки**, він отримає **помилку** у відповіді.
Наприклад, якщо клієнт спробує надіслати заголовок `tool` зі значенням `plumbus`, він отримає **помилку** з повідомленням про те, що параметр заголовка `tool` не дозволений:
```json
{
"detail": [
{
"type": "extra_forbidden",
"loc": ["header", "tool"],
"msg": "Extra inputs are not permitted",
"input": "plumbus",
}
]
}
```
## Підсумок
Ви можете використовувати **Pydantic моделі** для оголошення **заголовків** у **FastAPI**. 😎

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** автоматично конвертує їх.

120
docs/uk/docs/tutorial/metadata.md

@ -0,0 +1,120 @@
# Метадані та URL-адреси документації
Ви можете налаштувати кілька конфігурацій метаданих у Вашому додатку **FastAPI**.
## Метадані для API
Ви можете встановити такі поля, які використовуються в специфікації OpenAPI та в автоматично згенерованих інтерфейсах документації API:
| Параметр | Тип | Опис |
|------------|------|-------------|
| `title` | `str` | Назва API. |
| `summary` | `str` | Короткий опис API. <small>Доступно з OpenAPI 3.1.0, FastAPI 0.99.0.</small> |
| `description` | `str` | Більш детальний опис API. Може використовувати Markdown. |
| `version` | `string` | Версія API. Це версія Вашого додатка, а не OpenAPI. Наприклад, `2.5.0`. |
| `terms_of_service` | `str` | URL до умов використання API. Якщо вказано, має бути у форматі URL. |
| `contact` | `dict` | Інформація для контакту з API. Може містити кілька полів. <details><summary><code>contact</code> поля</summary><table><thead><tr><th>Параметр</th><th>Тип</th><th>Опис</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td>Ім'я контактної особи або організації.</td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>URL з інформацією для контакту. Повинен бути у форматі URL.</td></tr><tr><td><code>email</code></td><td><code>str</code></td><td>Email контактної особи або організації. Повинен бути у форматі електронної пошти.</td></tr></tbody></table></details> |
| `license_info` | `dict` | Інформація про ліцензію для API. Може містити кілька полів. <details><summary><code>license_info</code> поля</summary><table><thead><tr><th>Параметр</th><th>Тип</th><th>Опис</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td><strong>ОБОВ'ЯЗКОВО</strong> (якщо встановлено <code>license_info</code>). Назва ліцензії для API.</td></tr><tr><td><code>identifier</code></td><td><code>str</code></td><td>Ліцензійний вираз за <a href="https://spdx.org/licenses/" class="external-link" target="_blank">SPDX</a> для API. Поле <code>identifier</code> взаємовиключне з полем <code>url</code>. <small>Доступно з OpenAPI 3.1.0, FastAPI 0.99.0.</small></td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>URL до ліцензії, яка використовується для API. Повинен бути у форматі URL.</td></tr></tbody></table></details> |
Ви можете налаштувати їх наступним чином:
{* ../../docs_src/metadata/tutorial001.py hl[3:16, 19:32] *}
/// tip | Підказка
У полі `description` можна використовувати Markdown, і він буде відображатися у результаті.
///
З цією конфігурацією автоматична документація API виглядатиме так:
<img src="/img/tutorial/metadata/image01.png">
## Ідентифікатор ліцензії
З початку використання OpenAPI 3.1.0 та FastAPI 0.99.0 Ви також можете налаштувати `license_info` за допомогою `identifier` замість `url`.
Наприклад:
{* ../../docs_src/metadata/tutorial001_1.py hl[31] *}
## Метадані для тегів
Ви також можете додати додаткові метадані для різних тегів, які використовуються для групування операцій шляхів, за допомогою параметра `openapi_tags`.
Він приймає список, який містить один словник для кожного тега.
Кожен словник може містити:
* `name` (**обов'язково**): `str` з тією ж назвою тегу, яку Ви використовуєте у параметрі `tags` у Ваших *операціях шляху* та `APIRouter`s.
* `description`: `str` з коротким описом тегу. Може містити Markdown і буде відображено в інтерфейсі документації.
* `externalDocs`: `dict` який описує зовнішню документацію з такими полями:
* `description`: `str` з коротким описом зовнішньої документації.
* `url` (**обов'язково**): `str`з URL-адресою зовнішньої документації.
### Створення метаданих для тегів
Спробуймо це на прикладі з тегами для `users` та `items`.
Створіть метадані для своїх тегів і передайте їх у параметр `openapi_tags`:
{* ../../docs_src/metadata/tutorial004.py hl[3:16,18] *}
Зверніть увагу, що в описах можна використовувати Markdown, наприклад, "login" буде показано жирним шрифтом (**login**), а "fancy" буде показано курсивом (_fancy_).
/// tip | Порада
Не обов'язково додавати метадані для всіх тегів, які Ви використовуєте.
///
### Використання тегів
Використовуйте параметр `tags` зі своїми *операціями шляху*`APIRouter`) для призначення їх до різних тегів:
{* ../../docs_src/metadata/tutorial004.py hl[21,26] *}
/// info | Інформація
Детальніше про теги читайте в розділі [Конфігурація шляхів операцій](path-operation-configuration.md#tags){.internal-link target=_blank}.
///
### Перевірка документації
Якщо Ви зараз перевірите документацію, вона покаже всі додаткові метадані:
<img src="/img/tutorial/metadata/image02.png">
### Порядок тегів
Порядок кожного словника метаданих тегу також визначає порядок відображення в інтерфейсі документації.
Наприклад, хоча `users` мав би йти після `items` в алфавітному порядку, він відображається перед ними, оскільки ми додали його метадані як перший словник у списку.
## URL для OpenAPI
За замовчуванням схема OpenAPI надається за адресою `/openapi.json`.
Але Ви можете налаштувати це за допомогою параметра `openapi_url`.
Наприклад, щоб налаштувати його на `/api/v1/openapi.json`:
{* ../../docs_src/metadata/tutorial002.py hl[3] *}
Якщо Ви хочете повністю вимкнути схему OpenAPI, Ви можете встановити `openapi_url=None`, це також вимкне інтерфейси документації, які її використовують.
## URL-адреси документації
Ви можете налаштувати два інтерфейси користувача для документації, які включені:
* **Swagger UI**: доступний за адресою `/docs`.
* Ви можете змінити його URL за допомогою параметра `docs_url`.
* Ви можете вимкнути його, встановивши `docs_url=None`.
* **ReDoc**: доступний за адресою `/redoc`.
* Ви можете змінити його URL за допомогою параметра `redoc_url`.
* Ви можете вимкнути його, встановивши `redoc_url=None`.
Наприклад, щоб налаштувати Swagger UI на `/documentation` і вимкнути ReDoc:
{* ../../docs_src/metadata/tutorial003.py hl[3] *}

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` для оголошення вхідних параметрів у вигляді даних форми.

100
docs/uk/docs/tutorial/response-status-code.md

@ -0,0 +1,100 @@
# Статус коди Відповідей
Так само як Ви можете вказати модель відповіді, Ви також можете оголосити HTTP код статусу для відповіді за допомогою параметра `status_code` в будь-якій з *операцій шляху*:
* `@app.get()`
* `@app.post()`
* `@app.put()`
* `@app.delete()`
* тощо.
{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
/// note | Нотатка
Зверніть увагу, що `status_code` є параметром методу "декоратора" (`get`, `post` і т.д.), а не Вашої *функції операції шляху*, як усі інші параметри та тіло запиту.
///
Параметр `status_code` приймає число, яке відповідає HTTP коду статусу.
/// info | Інформація
`status_code` також може отримувати значення з `IntEnum`, наприклад, з Python <a href="https://docs.python.org/3/library/http.html#http.HTTPStatus" class="external-link" target="_blank">`http.HTTPStatus`</a>.
///
Він буде:
* Повертати вказаний код статусу у відповіді.
* Документувати його як такий у схемі OpenAPI (і, таким чином, в інтерфейсі користувача):
<img src="/img/tutorial/response-status-code/image01.png">
/// note | Нотатка
Деякі коди відповіді (див. наступний розділ) вказують, що відповідь не має тіла.
FastAPI знає про це і створить OpenAPI документацію, яка вказує, що тіла відповіді немає.
///
## Про HTTP статус коди
/// note | Нотатка
Якщо Ви вже знаєте, що таке HTTP коди статусу, переходьте до наступного розділу.
///
В HTTP Ви надсилаєте числовий код статусу з 3 цифр як частину відповіді.
Ці коди статусу мають пов’язану назву для їх розпізнавання, але найважливішою частиною є саме число.
Коротко:
* **`100 - 199`** "Інформаційні" відповіді. Ви рідко використовуєте їх напряму. Відповіді з такими кодами не можуть мати тіла.
* **`200 - 299`** "Успішні" відповіді. Це ті, які Ви використовуватимете найчастіше.
* `200` - код за замовчуванням, який означає, що все пройшло "OK".
* Інший приклад – `201`, "Created" (створено). Його зазвичай використовують після створення нового запису в базі даних.
* Особливий випадок – `204`, "No Content" (немає вмісту). Ця відповідь використовується, коли немає даних для повернення клієнту, тому відповідь не повинна мати тіла.
* **`300 - 399`** "Перенаправлення". Відповіді з цими кодами можуть мати або не мати тіла, за винятком `304`, "Not Modified" (не змінено), яка не повинна мати тіла.
* **`400 - 499`** "Помилка клієнта". Це другий тип, який Ви, ймовірно, будете використовувати найчастіше.
* Приклад `404`, "Not Found" (не знайдено).
* Для загальних помилок клієнта можна використовувати `400`.
* `500 - 599` "Помилки сервера". Ви майже ніколи не використовуєте їх напряму. Якщо в коді Вашого застосунку або на сервері щось пішло не так, автоматично буде повернено один із цих кодів статусу.
/// tip | Порада
Щоб дізнатися більше про кожен код статусу і призначення кожного з них, перегляньте документацію <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" class="external-link" target="_blank"><abbr title="Mozilla Developer Network">MDN</abbr> про HTTP коди статусу</a>.
///
## Легкий спосіб запам'ятати назви
Розглянемо ще раз попередній приклад:
{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
`201` - це код статусу для "Created" (створено).
Але Вам не потрібно запам'ятовувати, що означає кожен із цих кодів.
Ви можете використовувати зручні змінні з `fastapi.status`
{* ../../docs_src/response_status_code/tutorial002.py hl[1,6] *}
Ці змінні просто для зручності. Вони містять ті ж самі числа, але Ви можете скористатися автозаповненням в редакторі:
<img src="/img/tutorial/response-status-code/image02.png">
/// note | Технічні деталі
Ви також можете використати `from starlette import status`.
**FastAPI** надає ті ж самі змінні `starlette.status` як `fastapi.status`, просто для зручності розробника. Однак вони походять безпосередньо зі Starlette.
///
## Зміна значення за замовчуванням
Далі, у Посібнику для досвідчених користувачів{.internal-link target=_blank}, Ви дізнаєтесь, як повернути інший код статусу, ніж той, який Ви оголосили тут.

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

95
docs/zh/docs/tutorial/first-steps.md

@ -11,26 +11,42 @@
<div class="termy">
```console
$ uvicorn main:app --reload
$ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid">main.py</u>
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
<span style="color: green;">INFO</span>: Started reloader process [28720]
<span style="color: green;">INFO</span>: Started server process [28722]
<span style="color: green;">INFO</span>: Waiting for application startup.
<span style="color: green;">INFO</span>: Application startup complete.
```
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting development server 🚀
</div>
Searching for package file structure from directories
with <font color="#3465A4">__init__.py</font> files
Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
/// note
<span style="background-color:#007166"><font color="#D3D7CF"> module </font></span> 🐍 main.py
`uvicorn main:app` 命令含义如下:
<span style="background-color:#007166"><font color="#D3D7CF"> code </font></span> Importing the FastAPI app object from the module with
the following code:
* `main`:`main.py` 文件(一个 Python「模块」)。
* `app`:在 `main.py` 文件中通过 `app = FastAPI()` 创建的对象。
* `--reload`:让服务器在更新代码后重新启动。仅在开发时使用该选项。
<u style="text-decoration-style:solid">from </u><u style="text-decoration-style:solid"><b>main</b></u><u style="text-decoration-style:solid"> import </u><u style="text-decoration-style:solid"><b>app</b></u>
///
<span style="background-color:#007166"><font color="#D3D7CF"> app </font></span> Using import string: <font color="#3465A4">main:app</font>
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Server started at <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000</u></font>
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Documentation at <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000/docs</u></font>
<span style="background-color:#007166"><font color="#D3D7CF"> tip </font></span> Running in development mode, for production use:
<b>fastapi run</b>
Logs:
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Will watch for changes in these directories:
<b>[</b><font color="#4E9A06">&apos;/home/user/code/awesomeapp&apos;</font><b>]</b>
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Uvicorn running on <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000</u></font> <b>(</b>Press CTRL+C
to quit<b>)</b>
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started reloader process <b>[</b><font color="#34E2E2"><b>383138</b></font><b>]</b> using WatchFiles
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>383153</b></font><b>]</b>
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup.
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete.
```
</div>
在输出中,会有一行信息像下面这样:
@ -38,7 +54,6 @@ $ uvicorn main:app --reload
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
该行显示了你的应用在本机所提供服务的 URL 地址。
### 查看
@ -63,7 +78,7 @@ INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
前往 <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>
你将会看到可选的自动生成文档 (由 <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a> 提供)
你将会看到可选的自动生成文档 (由 <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a> 提供
![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
@ -77,9 +92,9 @@ INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
#### API「模式」
在这种场景下,OpenAPI 是一种规定如何定义 API 模式的规范。
在这种场景下,<a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> 是一种规定如何定义 API 模式的规范。
定义的 OpenAPI 模式将包括你的 API 路径,以及它们可能使用的参数等等。
「模式」的定义包括你的 API 路径,以及它们可能使用的参数等等。
#### 数据「模式」
@ -93,7 +108,7 @@ OpenAPI 为你的 API 定义 API 模式。该模式中包含了你的 API 发送
#### 查看 `openapi.json`
如果你对原始的 OpenAPI 模式长什么样子感到好奇,其实它只是一个自动生成的包含了所有 API 描述的 JSON
如果你对原始的 OpenAPI 模式长什么样子感到好奇,FastAPI 自动生成了包含所有 API 描述的 JSON(模式)
你可以直接在:<a href="http://127.0.0.1:8000/openapi.json" class="external-link" target="_blank">http://127.0.0.1:8000/openapi.json</a> 看到它。
@ -101,7 +116,7 @@ OpenAPI 为你的 API 定义 API 模式。该模式中包含了你的 API 发送
```JSON
{
"openapi": "3.0.2",
"openapi": "3.1.0",
"info": {
"title": "FastAPI",
"version": "0.1.0"
@ -140,7 +155,7 @@ OpenAPI 为你的 API 定义 API 模式。该模式中包含了你的 API 发送
`FastAPI` 是直接从 `Starlette` 继承的类。
你可以通过 `FastAPI` 使用所有的 Starlette 的功能。
你可以通过 `FastAPI` 使用所有的 <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> 的功能。
///
@ -152,34 +167,6 @@ OpenAPI 为你的 API 定义 API 模式。该模式中包含了你的 API 发送
这个实例将是创建你所有 API 的主要交互对象。
这个 `app` 同样在如下命令中被 `uvicorn` 所引用:
<div class="termy">
```console
$ uvicorn main:app --reload
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
如果你像下面这样创建应用:
{* ../../docs_src/first_steps/tutorial002.py hl[3] *}
将代码放入 `main.py` 文件中,然后你可以像下面这样运行 `uvicorn`
<div class="termy">
```console
$ uvicorn main:my_awesome_api --reload
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
### 步骤 3:创建一个*路径操作*
#### 路径
@ -279,13 +266,13 @@ https://example.com/items/foo
/// tip
可以随意使用任何一个操作(HTTP方法)。
可以随意使用任何一个操作(HTTP方法)。
**FastAPI** 没有强制要求操作有任何特定的含义。
此处提供的信息仅作为指导,而不是要求。
比如,当使用 GraphQL 时通常你所有的动作都通过 `post` 一种方法执行。
比如,当使用 GraphQL 时通常你所有的动作都通过 `POST` 一种方法执行。
///
@ -331,6 +318,6 @@ https://example.com/items/foo
* 导入 `FastAPI`
* 创建一个 `app` 实例。
* 编写一个**路径操作装饰器**`@app.get("/")`
* 编写一个**路径操作函数**(如上面的 `def root(): ...`
* 运行开发服务器(如 `uvicorn main:app --reload`
* 编写一个**路径操作装饰器**`@app.get("/")`
* 定义一个**路径操作函数**,如 `def root(): ...`
* 使用命令 `fastapi dev` 运行开发服务器

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}")

19
docs_src/header_param_models/tutorial003.py

@ -0,0 +1,19 @@
from typing import List, Union
from fastapi import FastAPI, Header
from pydantic import BaseModel
app = FastAPI()
class CommonHeaders(BaseModel):
host: str
save_data: bool
if_modified_since: Union[str, None] = None
traceparent: Union[str, None] = None
x_tag: List[str] = []
@app.get("/items/")
async def read_items(headers: CommonHeaders = Header(convert_underscores=False)):
return headers

22
docs_src/header_param_models/tutorial003_an.py

@ -0,0 +1,22 @@
from typing import List, Union
from fastapi import FastAPI, Header
from pydantic import BaseModel
from typing_extensions import Annotated
app = FastAPI()
class CommonHeaders(BaseModel):
host: str
save_data: bool
if_modified_since: Union[str, None] = None
traceparent: Union[str, None] = None
x_tag: List[str] = []
@app.get("/items/")
async def read_items(
headers: Annotated[CommonHeaders, Header(convert_underscores=False)],
):
return headers

21
docs_src/header_param_models/tutorial003_an_py310.py

@ -0,0 +1,21 @@
from typing import Annotated
from fastapi import FastAPI, Header
from pydantic import BaseModel
app = FastAPI()
class CommonHeaders(BaseModel):
host: str
save_data: bool
if_modified_since: str | None = None
traceparent: str | None = None
x_tag: list[str] = []
@app.get("/items/")
async def read_items(
headers: Annotated[CommonHeaders, Header(convert_underscores=False)],
):
return headers

21
docs_src/header_param_models/tutorial003_an_py39.py

@ -0,0 +1,21 @@
from typing import Annotated, Union
from fastapi import FastAPI, Header
from pydantic import BaseModel
app = FastAPI()
class CommonHeaders(BaseModel):
host: str
save_data: bool
if_modified_since: Union[str, None] = None
traceparent: Union[str, None] = None
x_tag: list[str] = []
@app.get("/items/")
async def read_items(
headers: Annotated[CommonHeaders, Header(convert_underscores=False)],
):
return headers

17
docs_src/header_param_models/tutorial003_py310.py

@ -0,0 +1,17 @@
from fastapi import FastAPI, Header
from pydantic import BaseModel
app = FastAPI()
class CommonHeaders(BaseModel):
host: str
save_data: bool
if_modified_since: str | None = None
traceparent: str | None = None
x_tag: list[str] = []
@app.get("/items/")
async def read_items(headers: CommonHeaders = Header(convert_underscores=False)):
return headers

19
docs_src/header_param_models/tutorial003_py39.py

@ -0,0 +1,19 @@
from typing import Union
from fastapi import FastAPI, Header
from pydantic import BaseModel
app = FastAPI()
class CommonHeaders(BaseModel):
host: str
save_data: bool
if_modified_since: Union[str, None] = None
traceparent: Union[str, None] = None
x_tag: list[str] = []
@app.get("/items/")
async def read_items(headers: CommonHeaders = Header(convert_underscores=False)):
return headers

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

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

Loading…
Cancel
Save