Browse Source

Merge branch 'master' into fix/response_model_default_factory

pull/9704/head
vvanglro 9 months ago
committed by GitHub
parent
commit
6f4a32f1cd
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 7
      README.md
  2. 13
      docs/en/data/sponsors.yml
  3. 2
      docs/en/data/sponsors_badge.yml
  4. 2
      docs/en/docs/advanced/generate-clients.md
  5. BIN
      docs/en/docs/img/sponsors/fine-banner.png
  6. BIN
      docs/en/docs/img/sponsors/fine.png
  7. BIN
      docs/en/docs/img/sponsors/stainless.png
  8. BIN
      docs/en/docs/img/sponsors/zuplo-banner.png
  9. BIN
      docs/en/docs/img/sponsors/zuplo.png
  10. 16
      docs/en/docs/release-notes.md
  11. 16
      docs/en/overrides/main.html
  12. 34
      docs/fr/docs/async.md
  13. 5
      docs/fr/docs/learn/index.md
  14. 240
      docs/pt/docs/advanced/additional-responses.md
  15. 69
      docs/pt/docs/advanced/additional-status-codes.md
  16. 138
      docs/pt/docs/advanced/advanced-dependencies.md
  17. 485
      docs/pt/docs/advanced/settings.md
  18. 11
      docs/pt/docs/how-to/index.md
  19. 497
      docs/pt/docs/tutorial/dependencies/classes-as-dependencies.md
  20. 353
      docs/pt/docs/tutorial/dependencies/index.md
  21. 134
      docs/zh/docs/tutorial/security/oauth2-jwt.md

7
README.md

@ -53,15 +53,18 @@ The key features are:
<a href="https://reflex.dev" target="_blank" title="Reflex"><img src="https://fastapi.tiangolo.com/img/sponsors/reflex.png"></a> <a href="https://reflex.dev" target="_blank" title="Reflex"><img src="https://fastapi.tiangolo.com/img/sponsors/reflex.png"></a>
<a href="https://github.com/scalar/scalar/?utm_source=fastapi&utm_medium=website&utm_campaign=main-badge" target="_blank" title="Scalar: Beautiful Open-Source API References from Swagger/OpenAPI files"><img src="https://fastapi.tiangolo.com/img/sponsors/scalar.svg"></a> <a href="https://github.com/scalar/scalar/?utm_source=fastapi&utm_medium=website&utm_campaign=main-badge" target="_blank" title="Scalar: Beautiful Open-Source API References from Swagger/OpenAPI files"><img src="https://fastapi.tiangolo.com/img/sponsors/scalar.svg"></a>
<a href="https://www.propelauth.com/?utm_source=fastapi&utm_campaign=1223&utm_medium=mainbadge" target="_blank" title="Auth, user management and more for your B2B product"><img src="https://fastapi.tiangolo.com/img/sponsors/propelauth.png"></a> <a href="https://www.propelauth.com/?utm_source=fastapi&utm_campaign=1223&utm_medium=mainbadge" target="_blank" title="Auth, user management and more for your B2B product"><img src="https://fastapi.tiangolo.com/img/sponsors/propelauth.png"></a>
<a href="https://www.withcoherence.com/?utm_medium=advertising&utm_source=fastapi&utm_campaign=banner%20january%2024" target="_blank" title="Coherence"><img src="https://fastapi.tiangolo.com/img/sponsors/coherence.png"></a> <a href="https://docs.withcoherence.com/configuration/frameworks/?utm_medium=advertising&utm_source=fastapi&utm_campaign=docs#fastapi-example" target="_blank" title="Coherence"><img src="https://fastapi.tiangolo.com/img/sponsors/coherence.png"></a>
<a href="https://www.mongodb.com/developer/languages/python/python-quickstart-fastapi/?utm_campaign=fastapi_framework&utm_source=fastapi_sponsorship&utm_medium=web_referral" target="_blank" title="Simplify Full Stack Development with FastAPI & MongoDB"><img src="https://fastapi.tiangolo.com/img/sponsors/mongodb.png"></a> <a href="https://www.mongodb.com/developer/languages/python/python-quickstart-fastapi/?utm_campaign=fastapi_framework&utm_source=fastapi_sponsorship&utm_medium=web_referral" target="_blank" title="Simplify Full Stack Development with FastAPI & MongoDB"><img src="https://fastapi.tiangolo.com/img/sponsors/mongodb.png"></a>
<a href="https://konghq.com/products/kong-konnect/register?utm_medium=referral&utm_source=github&utm_campaign=platform&utm_content=fast-api" target="_blank" title="Kong Konnect - API management platform"><img src="https://fastapi.tiangolo.com/img/sponsors/kong.png"></a> <a href="https://konghq.com/products/kong-konnect?utm_medium=referral&utm_source=github&utm_campaign=platform&utm_content=fast-api" target="_blank" title="Kong Konnect - API management platform"><img src="https://fastapi.tiangolo.com/img/sponsors/kong.png"></a>
<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://fine.dev?ref=fastapibadge" target="_blank" title="Fine's AI FastAPI Workflow: Effortlessly Deploy and Integrate FastAPI into Your Project"><img src="https://fastapi.tiangolo.com/img/sponsors/fine.png"></a>
<a href="https://training.talkpython.fm/fastapi-courses" target="_blank" title="FastAPI video courses on demand from people you trust"><img src="https://fastapi.tiangolo.com/img/sponsors/talkpython-v2.jpg"></a> <a href="https://training.talkpython.fm/fastapi-courses" target="_blank" title="FastAPI video courses on demand from people you trust"><img src="https://fastapi.tiangolo.com/img/sponsors/talkpython-v2.jpg"></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://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://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://speakeasyapi.dev?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> <a href="https://speakeasyapi.dev?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>
<a href="https://www.svix.com/" target="_blank" title="Svix - Webhooks as a service"><img src="https://fastapi.tiangolo.com/img/sponsors/svix.svg"></a> <a href="https://www.svix.com/" target="_blank" title="Svix - Webhooks as a service"><img src="https://fastapi.tiangolo.com/img/sponsors/svix.svg"></a>
<a href="https://www.codacy.com/?utm_source=github&utm_medium=sponsors&utm_id=pioneers" target="_blank" title="Take code reviews from hours to minutes"><img src="https://fastapi.tiangolo.com/img/sponsors/codacy.png"></a> <a href="https://www.codacy.com/?utm_source=github&utm_medium=sponsors&utm_id=pioneers" target="_blank" title="Take code reviews from hours to minutes"><img src="https://fastapi.tiangolo.com/img/sponsors/codacy.png"></a>
<a href="https://www.stainlessapi.com/?utm_source=fastapi&utm_medium=referral" target="_blank" title="Stainless | Generate best-in-class SDKs"><img src="https://fastapi.tiangolo.com/img/sponsors/stainless.png"></a>
<!-- /sponsors --> <!-- /sponsors -->

13
docs/en/data/sponsors.yml

@ -20,15 +20,21 @@ gold:
- url: https://www.propelauth.com/?utm_source=fastapi&utm_campaign=1223&utm_medium=mainbadge - url: https://www.propelauth.com/?utm_source=fastapi&utm_campaign=1223&utm_medium=mainbadge
title: Auth, user management and more for your B2B product title: Auth, user management and more for your B2B product
img: https://fastapi.tiangolo.com/img/sponsors/propelauth.png img: https://fastapi.tiangolo.com/img/sponsors/propelauth.png
- url: https://www.withcoherence.com/?utm_medium=advertising&utm_source=fastapi&utm_campaign=banner%20january%2024 - url: https://docs.withcoherence.com/configuration/frameworks/?utm_medium=advertising&utm_source=fastapi&utm_campaign=docs#fastapi-example
title: Coherence title: Coherence
img: https://fastapi.tiangolo.com/img/sponsors/coherence.png img: https://fastapi.tiangolo.com/img/sponsors/coherence.png
- url: https://www.mongodb.com/developer/languages/python/python-quickstart-fastapi/?utm_campaign=fastapi_framework&utm_source=fastapi_sponsorship&utm_medium=web_referral - url: https://www.mongodb.com/developer/languages/python/python-quickstart-fastapi/?utm_campaign=fastapi_framework&utm_source=fastapi_sponsorship&utm_medium=web_referral
title: Simplify Full Stack Development with FastAPI & MongoDB title: Simplify Full Stack Development with FastAPI & MongoDB
img: https://fastapi.tiangolo.com/img/sponsors/mongodb.png img: https://fastapi.tiangolo.com/img/sponsors/mongodb.png
- url: https://konghq.com/products/kong-konnect/register?utm_medium=referral&utm_source=github&utm_campaign=platform&utm_content=fast-api - url: https://konghq.com/products/kong-konnect?utm_medium=referral&utm_source=github&utm_campaign=platform&utm_content=fast-api
title: Kong Konnect - API management platform title: Kong Konnect - API management platform
img: https://fastapi.tiangolo.com/img/sponsors/kong.png img: https://fastapi.tiangolo.com/img/sponsors/kong.png
- url: https://zuplo.link/fastapi-gh
title: 'Zuplo: Scale, Protect, Document, and Monetize your FastAPI'
img: https://fastapi.tiangolo.com/img/sponsors/zuplo.png
- url: https://fine.dev?ref=fastapibadge
title: "Fine's AI FastAPI Workflow: Effortlessly Deploy and Integrate FastAPI into Your Project"
img: https://fastapi.tiangolo.com/img/sponsors/fine.png
silver: silver:
- url: https://training.talkpython.fm/fastapi-courses - url: https://training.talkpython.fm/fastapi-courses
title: FastAPI video courses on demand from people you trust title: FastAPI video courses on demand from people you trust
@ -48,6 +54,9 @@ silver:
- url: https://www.codacy.com/?utm_source=github&utm_medium=sponsors&utm_id=pioneers - url: https://www.codacy.com/?utm_source=github&utm_medium=sponsors&utm_id=pioneers
title: Take code reviews from hours to minutes title: Take code reviews from hours to minutes
img: https://fastapi.tiangolo.com/img/sponsors/codacy.png img: https://fastapi.tiangolo.com/img/sponsors/codacy.png
- url: https://www.stainlessapi.com/?utm_source=fastapi&utm_medium=referral
title: Stainless | Generate best-in-class SDKs
img: https://fastapi.tiangolo.com/img/sponsors/stainless.png
bronze: bronze:
- url: https://www.exoflare.com/open-source/?utm_source=FastAPI&utm_campaign=open_source - url: https://www.exoflare.com/open-source/?utm_source=FastAPI&utm_campaign=open_source
title: Biosecurity risk assessments made easy. title: Biosecurity risk assessments made easy.

2
docs/en/data/sponsors_badge.yml

@ -28,3 +28,5 @@ logins:
- bump-sh - bump-sh
- andrew-propelauth - andrew-propelauth
- svix - svix
- zuplo-oss
- Kong

2
docs/en/docs/advanced/generate-clients.md

@ -20,7 +20,7 @@ Some of them also ✨ [**sponsor FastAPI**](../help-fastapi.md#sponsor-the-autho
And it shows their true commitment to FastAPI and its **community** (you), as they not only want to provide you a **good service** but also want to make sure you have a **good and healthy framework**, FastAPI. 🙇 And it shows their true commitment to FastAPI and its **community** (you), as they not only want to provide you a **good service** but also want to make sure you have a **good and healthy framework**, FastAPI. 🙇
For example, you might want to try <a href="https://speakeasyapi.dev/?utm_source=fastapi+repo&utm_medium=github+sponsorship" class="external-link" target="_blank">Speakeasy</a>. For example, you might want to try <a href="https://speakeasyapi.dev/?utm_source=fastapi+repo&utm_medium=github+sponsorship" class="external-link" target="_blank">Speakeasy</a> and <a href="https://www.stainlessapi.com/?utm_source=fastapi&utm_medium=referral" class="external-link" target="_blank">Stainless</a>.
There are also several other companies offering similar services that you can search and find online. 🤓 There are also several other companies offering similar services that you can search and find online. 🤓

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

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

@ -32,6 +32,16 @@ hide:
### Translations ### Translations
* 🌐 Update Chinese translation for `docs/tutorial/security/oauth2-jwt.md`. PR [#11781](https://github.com/tiangolo/fastapi/pull/11781) by [@logan2d5](https://github.com/logan2d5).
* 📝 Fix image missing in French translation for `docs/fr/docs/async.md` . PR [#11787](https://github.com/tiangolo/fastapi/pull/11787) by [@pe-brian](https://github.com/pe-brian).
* 🌐 Add Portuguese translation for `docs/pt/docs/advanced/advanced-dependencies.md`. PR [#11775](https://github.com/tiangolo/fastapi/pull/11775) by [@ceb10n](https://github.com/ceb10n).
* 🌐 Add Portuguese translation for `docs/pt/docs/tutorial/dependencies/classes-as-dependencies.md`. PR [#11768](https://github.com/tiangolo/fastapi/pull/11768) by [@Joao-Pedro-P-Holanda](https://github.com/Joao-Pedro-P-Holanda).
* 🌐 Add Portuguese translation for `docs/pt/docs/advanced/additional-status-codes.md`. PR [#11753](https://github.com/tiangolo/fastapi/pull/11753) by [@ceb10n](https://github.com/ceb10n).
* 🌐 Add Portuguese translation for `docs/pt/docs/tutorial/dependencies/index.md`. PR [#11757](https://github.com/tiangolo/fastapi/pull/11757) by [@Joao-Pedro-P-Holanda](https://github.com/Joao-Pedro-P-Holanda).
* 🌐 Add Portuguese translation for `docs/pt/docs/advanced/settings.md`. PR [#11739](https://github.com/tiangolo/fastapi/pull/11739) by [@Joao-Pedro-P-Holanda](https://github.com/Joao-Pedro-P-Holanda).
* 🌐 Add French translation for `docs/fr/docs/learn/index.md`. PR [#11712](https://github.com/tiangolo/fastapi/pull/11712) by [@benjaminvandammeholberton](https://github.com/benjaminvandammeholberton).
* 🌐 Add Portuguese translation for `docs/pt/docs/how-to/index.md`. PR [#11731](https://github.com/tiangolo/fastapi/pull/11731) by [@vhsenna](https://github.com/vhsenna).
* 🌐 Add Portuguese translation for `docs/pt/docs/advanced/additional-responses.md`. PR [#11736](https://github.com/tiangolo/fastapi/pull/11736) by [@ceb10n](https://github.com/ceb10n).
* 🌐 Add Portuguese translation for `docs/pt/docs/advanced/benchmarks.md`. PR [#11713](https://github.com/tiangolo/fastapi/pull/11713) by [@ceb10n](https://github.com/ceb10n). * 🌐 Add Portuguese translation for `docs/pt/docs/advanced/benchmarks.md`. PR [#11713](https://github.com/tiangolo/fastapi/pull/11713) by [@ceb10n](https://github.com/ceb10n).
* 🌐 Fix Korean translation for `docs/ko/docs/tutorial/response-status-code.md`. PR [#11718](https://github.com/tiangolo/fastapi/pull/11718) by [@nayeonkinn](https://github.com/nayeonkinn). * 🌐 Fix Korean translation for `docs/ko/docs/tutorial/response-status-code.md`. PR [#11718](https://github.com/tiangolo/fastapi/pull/11718) by [@nayeonkinn](https://github.com/nayeonkinn).
* 🌐 Add Korean translation for `docs/ko/docs/tutorial/extra-data-types.md`. PR [#11711](https://github.com/tiangolo/fastapi/pull/11711) by [@nayeonkinn](https://github.com/nayeonkinn). * 🌐 Add Korean translation for `docs/ko/docs/tutorial/extra-data-types.md`. PR [#11711](https://github.com/tiangolo/fastapi/pull/11711) by [@nayeonkinn](https://github.com/nayeonkinn).
@ -56,6 +66,12 @@ hide:
### Internal ### Internal
* 🔧 Update sponsors: add Fine. PR [#11784](https://github.com/tiangolo/fastapi/pull/11784) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Tweak sponsors: Kong URL. PR [#11765](https://github.com/tiangolo/fastapi/pull/11765) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Tweak sponsors: Kong URL. PR [#11764](https://github.com/tiangolo/fastapi/pull/11764) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Update sponsors, add Stainless. PR [#11763](https://github.com/tiangolo/fastapi/pull/11763) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Update sponsors, add Zuplo. PR [#11729](https://github.com/tiangolo/fastapi/pull/11729) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Update Sponsor link: Coherence. PR [#11730](https://github.com/tiangolo/fastapi/pull/11730) by [@tiangolo](https://github.com/tiangolo).
* 👥 Update FastAPI People. PR [#11669](https://github.com/tiangolo/fastapi/pull/11669) by [@tiangolo](https://github.com/tiangolo). * 👥 Update FastAPI People. PR [#11669](https://github.com/tiangolo/fastapi/pull/11669) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Add sponsor Kong. PR [#11662](https://github.com/tiangolo/fastapi/pull/11662) by [@tiangolo](https://github.com/tiangolo). * 🔧 Add sponsor Kong. PR [#11662](https://github.com/tiangolo/fastapi/pull/11662) by [@tiangolo](https://github.com/tiangolo).
* 👷 Update Smokeshow, fix sync download artifact and smokeshow configs. PR [#11563](https://github.com/tiangolo/fastapi/pull/11563) by [@tiangolo](https://github.com/tiangolo). * 👷 Update Smokeshow, fix sync download artifact and smokeshow configs. PR [#11563](https://github.com/tiangolo/fastapi/pull/11563) by [@tiangolo](https://github.com/tiangolo).

16
docs/en/overrides/main.html

@ -65,7 +65,7 @@
</a> </a>
</div> </div>
<div class="item"> <div class="item">
<a title="Coherence" style="display: block; position: relative;" href="https://www.withcoherence.com/?utm_medium=advertising&utm_source=fastapi&utm_campaign=banner%20january%2024" target="_blank"> <a title="Coherence" style="display: block; position: relative;" href="https://docs.withcoherence.com/configuration/frameworks/?utm_medium=advertising&utm_source=fastapi&utm_campaign=docs#fastapi-example" target="_blank">
<span class="sponsor-badge">sponsor</span> <span class="sponsor-badge">sponsor</span>
<img class="sponsor-image" src="/img/sponsors/coherence-banner.png" /> <img class="sponsor-image" src="/img/sponsors/coherence-banner.png" />
</a> </a>
@ -77,11 +77,23 @@
</a> </a>
</div> </div>
<div class="item"> <div class="item">
<a title="Kong Konnect - API management platform" style="display: block; position: relative;" href="https://konghq.com/products/kong-konnect/register?utm_medium=referral&utm_source=github&utm_campaign=platform&utm_content=fast-api" target="_blank"> <a title="Kong Konnect - API management platform" style="display: block; position: relative;" href="https://konghq.com/products/kong-konnect?utm_medium=referral&utm_source=github&utm_campaign=platform&utm_content=fast-api" target="_blank">
<span class="sponsor-badge">sponsor</span> <span class="sponsor-badge">sponsor</span>
<img class="sponsor-image" src="/img/sponsors/kong-banner.png" /> <img class="sponsor-image" src="/img/sponsors/kong-banner.png" />
</a> </a>
</div> </div>
<div class="item">
<a title="Zuplo: Scale, Protect, Document, and Monetize your FastAPI" style="display: block; position: relative;" href="https://zuplo.link/fastapi-web" target="_blank">
<span class="sponsor-badge">sponsor</span>
<img class="sponsor-image" src="/img/sponsors/zuplo-banner.png" />
</a>
</div>
<div class="item">
<a title="Fine's AI FastAPI Workflow: Effortlessly Deploy and Integrate FastAPI into Your Project" style="display: block; position: relative;" href="https://fine.dev?ref=fastapibanner" target="_blank">
<span class="sponsor-badge">sponsor</span>
<img class="sponsor-image" src="/img/sponsors/fine-banner.png" />
</a>
</div>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

34
docs/fr/docs/async.md

@ -103,24 +103,41 @@ Pour expliquer la différence, voici une histoire de burgers :
Vous amenez votre crush 😍 dans votre fast food 🍔 favori, et faites la queue pendant que le serveur 💁 prend les commandes des personnes devant vous. Vous amenez votre crush 😍 dans votre fast food 🍔 favori, et faites la queue pendant que le serveur 💁 prend les commandes des personnes devant vous.
<img src="/img/async/concurrent-burgers/concurrent-burgers-01.png" class="illustration">
Puis vient votre tour, vous commandez alors 2 magnifiques burgers 🍔 pour votre crush 😍 et vous. Puis vient votre tour, vous commandez alors 2 magnifiques burgers 🍔 pour votre crush 😍 et vous.
Vous payez 💸. <img src="/img/async/concurrent-burgers/concurrent-burgers-02.png" class="illustration">
Le serveur 💁 dit quelque chose à son collègue dans la cuisine 👨‍🍳 pour qu'il sache qu'il doit préparer vos burgers 🍔 (bien qu'il soit déjà en train de préparer ceux des clients précédents). Le serveur 💁 dit quelque chose à son collègue dans la cuisine 👨‍🍳 pour qu'il sache qu'il doit préparer vos burgers 🍔 (bien qu'il soit déjà en train de préparer ceux des clients précédents).
<img src="/img/async/concurrent-burgers/concurrent-burgers-03.png" class="illustration">
Vous payez 💸.
Le serveur 💁 vous donne le numéro assigné à votre commande. Le serveur 💁 vous donne le numéro assigné à votre commande.
<img src="/img/async/concurrent-burgers/concurrent-burgers-04.png" class="illustration">
Pendant que vous attendez, vous allez choisir une table avec votre crush 😍, vous discutez avec votre crush 😍 pendant un long moment (les burgers étant "magnifiques" ils sont très longs à préparer ✨🍔✨). Pendant que vous attendez, vous allez choisir une table avec votre crush 😍, vous discutez avec votre crush 😍 pendant un long moment (les burgers étant "magnifiques" ils sont très longs à préparer ✨🍔✨).
Pendant que vous êtes assis à table, en attendant que les burgers 🍔 soient prêts, vous pouvez passer ce temps à admirer à quel point votre crush 😍 est géniale, mignonne et intelligente ✨😍✨. Pendant que vous êtes assis à table, en attendant que les burgers 🍔 soient prêts, vous pouvez passer ce temps à admirer à quel point votre crush 😍 est géniale, mignonne et intelligente ✨😍✨.
<img src="/img/async/concurrent-burgers/concurrent-burgers-05.png" class="illustration">
Pendant que vous discutez avec votre crush 😍, de temps en temps vous jetez un coup d'oeil au nombre affiché au-dessus du comptoir pour savoir si c'est à votre tour d'être servis. Pendant que vous discutez avec votre crush 😍, de temps en temps vous jetez un coup d'oeil au nombre affiché au-dessus du comptoir pour savoir si c'est à votre tour d'être servis.
Jusqu'au moment où c'est (enfin) votre tour. Vous allez au comptoir, récupérez vos burgers 🍔 et revenez à votre table. Jusqu'au moment où c'est (enfin) votre tour. Vous allez au comptoir, récupérez vos burgers 🍔 et revenez à votre table.
<img src="/img/async/concurrent-burgers/concurrent-burgers-06.png" class="illustration">
Vous et votre crush 😍 mangez les burgers 🍔 et passez un bon moment ✨. Vous et votre crush 😍 mangez les burgers 🍔 et passez un bon moment ✨.
<img src="/img/async/concurrent-burgers/concurrent-burgers-07.png" class="illustration">
!!! info
Illustrations proposées par <a href="https://www.instagram.com/ketrinadrawsalot" class="external-link" target="_blank">Ketrina Thompson</a>. 🎨
--- ---
Imaginez que vous êtes l'ordinateur / le programme 🤖 dans cette histoire. Imaginez que vous êtes l'ordinateur / le programme 🤖 dans cette histoire.
@ -149,26 +166,41 @@ Vous attendez pendant que plusieurs (disons 8) serveurs qui sont aussi des cuisi
Chaque personne devant vous attend 🕙 que son burger 🍔 soit prêt avant de quitter le comptoir car chacun des 8 serveurs va lui-même préparer le burger directement avant de prendre la commande suivante. Chaque personne devant vous attend 🕙 que son burger 🍔 soit prêt avant de quitter le comptoir car chacun des 8 serveurs va lui-même préparer le burger directement avant de prendre la commande suivante.
<img src="/img/async/parallel-burgers/parallel-burgers-01.png" class="illustration">
Puis c'est enfin votre tour, vous commandez 2 magnifiques burgers 🍔 pour vous et votre crush 😍. Puis c'est enfin votre tour, vous commandez 2 magnifiques burgers 🍔 pour vous et votre crush 😍.
Vous payez 💸. Vous payez 💸.
<img src="/img/async/parallel-burgers/parallel-burgers-02.png" class="illustration">
Le serveur va dans la cuisine 👨‍🍳. Le serveur va dans la cuisine 👨‍🍳.
Vous attendez devant le comptoir afin que personne ne prenne vos burgers 🍔 avant vous, vu qu'il n'y a pas de numéro de commande. Vous attendez devant le comptoir afin que personne ne prenne vos burgers 🍔 avant vous, vu qu'il n'y a pas de numéro de commande.
<img src="/img/async/parallel-burgers/parallel-burgers-03.png" class="illustration">
Vous et votre crush 😍 étant occupés à vérifier que personne ne passe devant vous prendre vos burgers au moment où ils arriveront 🕙, vous ne pouvez pas vous préoccuper de votre crush 😞. Vous et votre crush 😍 étant occupés à vérifier que personne ne passe devant vous prendre vos burgers au moment où ils arriveront 🕙, vous ne pouvez pas vous préoccuper de votre crush 😞.
C'est du travail "synchrone", vous être "synchronisés" avec le serveur/cuisinier 👨‍🍳. Vous devez attendre 🕙 et être présent au moment exact où le serveur/cuisinier 👨‍🍳 finira les burgers 🍔 et vous les donnera, sinon quelqu'un risque de vous les prendre. C'est du travail "synchrone", vous être "synchronisés" avec le serveur/cuisinier 👨‍🍳. Vous devez attendre 🕙 et être présent au moment exact où le serveur/cuisinier 👨‍🍳 finira les burgers 🍔 et vous les donnera, sinon quelqu'un risque de vous les prendre.
<img src="/img/async/parallel-burgers/parallel-burgers-04.png" class="illustration">
Puis le serveur/cuisinier 👨‍🍳 revient enfin avec vos burgers 🍔, après un long moment d'attente 🕙 devant le comptoir. Puis le serveur/cuisinier 👨‍🍳 revient enfin avec vos burgers 🍔, après un long moment d'attente 🕙 devant le comptoir.
<img src="/img/async/parallel-burgers/parallel-burgers-05.png" class="illustration">
Vous prenez vos burgers 🍔 et allez à une table avec votre crush 😍 Vous prenez vos burgers 🍔 et allez à une table avec votre crush 😍
Vous les mangez, et vous avez terminé 🍔 ⏹. Vous les mangez, et vous avez terminé 🍔 ⏹.
<img src="/img/async/parallel-burgers/parallel-burgers-06.png" class="illustration">
Durant tout ce processus, il n'y a presque pas eu de discussions ou de flirts car la plupart de votre temps à été passé à attendre 🕙 devant le comptoir 😞. Durant tout ce processus, il n'y a presque pas eu de discussions ou de flirts car la plupart de votre temps à été passé à attendre 🕙 devant le comptoir 😞.
!!! info
Illustrations proposées par <a href="https://www.instagram.com/ketrinadrawsalot" class="external-link" target="_blank">Ketrina Thompson</a>. 🎨
--- ---
Dans ce scénario de burgers parallèles, vous êtes un ordinateur / programme 🤖 avec deux processeurs (vous et votre crush 😍) attendant 🕙 à deux et dédiant votre attention 🕙 à "attendre devant le comptoir" pour une longue durée. Dans ce scénario de burgers parallèles, vous êtes un ordinateur / programme 🤖 avec deux processeurs (vous et votre crush 😍) attendant 🕙 à deux et dédiant votre attention 🕙 à "attendre devant le comptoir" pour une longue durée.

5
docs/fr/docs/learn/index.md

@ -0,0 +1,5 @@
# Apprendre
Voici les sections introductives et les tutoriels pour apprendre **FastAPI**.
Vous pouvez considérer ceci comme un **manuel**, un **cours**, la **méthode officielle** et recommandée pour appréhender FastAPI. 😎

240
docs/pt/docs/advanced/additional-responses.md

@ -0,0 +1,240 @@
# Retornos Adicionais no OpenAPI
!!! warning "Aviso"
Este é um tema bem avançado.
Se você está começando com o **FastAPI**, provavelmente você não precisa disso.
Você pode declarar retornos adicionais, com códigos de status adicionais, media types, descrições, etc.
Essas respostas adicionais serão incluídas no esquema do OpenAPI, e também aparecerão na documentação da API.
Porém para as respostas adicionais, você deve garantir que está retornando um `Response` como por exemplo o `JSONResponse` diretamente, junto com o código de status e o conteúdo.
## Retorno Adicional com `model`
Você pode fornecer o parâmetro `responses` aos seus *decoradores de caminho*.
Este parâmetro recebe um `dict`, as chaves são os códigos de status para cada retorno, como por exemplo `200`, e os valores são um outro `dict` com a informação de cada um deles.
Cada um desses `dict` de retorno pode ter uma chave `model`, contendo um modelo do Pydantic, assim como o `response_model`.
O **FastAPI** pegará este modelo, gerará o esquema JSON dele e incluirá no local correto do OpenAPI.
Por exemplo, para declarar um outro retorno com o status code `404` e um modelo do Pydantic chamado `Message`, você pode escrever:
```Python hl_lines="18 22"
{!../../../docs_src/additional_responses/tutorial001.py!}
```
!!! note "Nota"
Lembre-se que você deve retornar o `JSONResponse` diretamente.
!!! info "Informação"
A chave `model` não é parte do OpenAPI.
O **FastAPI** pegará o modelo do Pydantic, gerará o `JSON Schema`, e adicionará no local correto.
O local correto é:
* Na chave `content`, que tem como valor um outro objeto JSON (`dict`) que contém:
* Uma chave com o media type, como por exemplo `application/json`, que contém como valor um outro objeto JSON, contendo::
* Uma chave `schema`, que contém como valor o JSON Schema do modelo, sendo este o local correto.
* O **FastAPI** adiciona aqui a referência dos esquemas JSON globais que estão localizados em outro lugar, ao invés de incluí-lo diretamente. Deste modo, outras aplicações e clientes podem utilizar estes esquemas JSON diretamente, fornecer melhores ferramentas de geração de código, etc.
O retorno gerado no OpenAI para esta *operação de caminho* será:
```JSON hl_lines="3-12"
{
"responses": {
"404": {
"description": "Additional Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Message"
}
}
}
},
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Item"
}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
}
}
```
Os esquemas são referenciados em outro local dentro do esquema OpenAPI:
```JSON hl_lines="4-16"
{
"components": {
"schemas": {
"Message": {
"title": "Message",
"required": [
"message"
],
"type": "object",
"properties": {
"message": {
"title": "Message",
"type": "string"
}
}
},
"Item": {
"title": "Item",
"required": [
"id",
"value"
],
"type": "object",
"properties": {
"id": {
"title": "Id",
"type": "string"
},
"value": {
"title": "Value",
"type": "string"
}
}
},
"ValidationError": {
"title": "ValidationError",
"required": [
"loc",
"msg",
"type"
],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {
"type": "string"
}
},
"msg": {
"title": "Message",
"type": "string"
},
"type": {
"title": "Error Type",
"type": "string"
}
}
},
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {
"$ref": "#/components/schemas/ValidationError"
}
}
}
}
}
}
}
```
## Media types adicionais para o retorno principal
Você pode utilizar o mesmo parâmetro `responses` para adicionar diferentes media types para o mesmo retorno principal.
Por exemplo, você pode adicionar um media type adicional de `image/png`, declarando que a sua *operação de caminho* pode retornar um objeto JSON (com o media type `application/json`) ou uma imagem PNG:
```Python hl_lines="19-24 28"
{!../../../docs_src/additional_responses/tutorial002.py!}
```
!!! note "Nota"
Note que você deve retornar a imagem utilizando um `FileResponse` diretamente.
!!! info "Informação"
A menos que você especifique um media type diferente explicitamente em seu parâmetro `responses`, o FastAPI assumirá que o retorno possui o mesmo media type contido na classe principal de retorno (padrão `application/json`).
Porém se você especificou uma classe de retorno com o valor `None` como media type, o FastAPI utilizará `application/json` para qualquer retorno adicional que possui um modelo associado.
## Combinando informações
Você também pode combinar informações de diferentes lugares, incluindo os parâmetros `response_model`, `status_code`, e `responses`.
Você pode declarar um `response_model`, utilizando o código de status padrão `200` (ou um customizado caso você precise), e depois adicionar informações adicionais para esse mesmo retorno em `responses`, diretamente no esquema OpenAPI.
O **FastAPI** manterá as informações adicionais do `responses`, e combinará com o esquema JSON do seu modelo.
Por exemplo, você pode declarar um retorno com o código de status `404` que utiliza um modelo do Pydantic que possui um `description` customizado.
E um retorno com o código de status `200` que utiliza o seu `response_model`, porém inclui um `example` customizado:
```Python hl_lines="20-31"
{!../../../docs_src/additional_responses/tutorial003.py!}
```
Isso será combinado e incluído em seu OpenAPI, e disponibilizado na documentação da sua API:
<img src="/img/tutorial/additional-responses/image01.png">
## Combinar retornos predefinidos e personalizados
Você pode querer possuir alguns retornos predefinidos que são aplicados para diversas *operações de caminho*, porém você deseja combinar com retornos personalizados que são necessários para cada *operação de caminho*.
Para estes casos, você pode utilizar a técnica do Python de "desempacotamento" de um `dict` utilizando `**dict_to_unpack`:
```Python
old_dict = {
"old key": "old value",
"second old key": "second old value",
}
new_dict = {**old_dict, "new key": "new value"}
```
Aqui, o `new_dict` terá todos os pares de chave-valor do `old_dict` mais o novo par de chave-valor:
```Python
{
"old key": "old value",
"second old key": "second old value",
"new key": "new value",
}
```
Você pode utilizar essa técnica para reutilizar alguns retornos predefinidos nas suas *operações de caminho* e combiná-las com personalizações adicionais.
Por exemplo:
```Python hl_lines="13-17 26"
{!../../../docs_src/additional_responses/tutorial004.py!}
```
## Mais informações sobre retornos OpenAPI
Para verificar exatamente o que você pode incluir nos retornos, você pode conferir estas seções na especificação do OpenAPI:
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responsesObject" class="external-link" target="_blank">Objeto de Retorno OpenAPI</a>, inclui o `Response Object`.
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responseObject" class="external-link" target="_blank">Objeto de Retorno OpenAPI</a>, você pode incluir qualquer coisa dele diretamente em cada retorno dentro do seu parâmetro `responses`. Incluindo `description`, `headers`, `content` (dentro dele que você declara diferentes media types e esquemas JSON), e `links`.

69
docs/pt/docs/advanced/additional-status-codes.md

@ -0,0 +1,69 @@
# Códigos de status adicionais
Por padrão, o **FastAPI** retornará as respostas utilizando o `JSONResponse`, adicionando o conteúdo do retorno da sua *operação de caminho* dentro do `JSONResponse`.
Ele usará o código de status padrão ou o que você definir na sua *operação de caminho*.
## Códigos de status adicionais
Caso você queira retornar códigos de status adicionais além do código principal, você pode fazer isso retornando um `Response` diretamente, como por exemplo um `JSONResponse`, e definir os códigos de status adicionais diretamente.
Por exemplo, vamos dizer que você deseja ter uma *operação de caminho* que permita atualizar itens, e retornar um código de status HTTP 200 "OK" quando for bem sucedido.
Mas você também deseja aceitar novos itens. E quando os itens não existiam, ele os cria, e retorna o código de status HTTP 201 "Created.
Para conseguir isso, importe `JSONResponse` e retorne o seu conteúdo diretamente, definindo o `status_code` que você deseja:
=== "Python 3.10+"
```Python hl_lines="4 25"
{!> ../../../docs_src/additional_status_codes/tutorial001_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="4 25"
{!> ../../../docs_src/additional_status_codes/tutorial001_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="4 26"
{!> ../../../docs_src/additional_status_codes/tutorial001_an.py!}
```
=== "Python 3.10+ non-Annotated"
!!! tip "Dica"
Faça uso da versão `Annotated` quando possível.
```Python hl_lines="2 23"
{!> ../../../docs_src/additional_status_codes/tutorial001_py310.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip "Dica"
Faça uso da versão `Annotated` quando possível.
```Python hl_lines="4 25"
{!> ../../../docs_src/additional_status_codes/tutorial001.py!}
```
!!! warning "Aviso"
Quando você retorna um `Response` diretamente, como no exemplo acima, ele será retornado diretamente.
Ele não será serializado com um modelo, etc.
Garanta que ele tenha toda informação que você deseja, e que os valores sejam um JSON válido (caso você esteja usando `JSONResponse`).
!!! note "Detalhes técnicos"
Você também pode utilizar `from starlette.responses import JSONResponse`.
O **FastAPI** disponibiliza o `starlette.responses` como `fastapi.responses` apenas por conveniência para você, o programador. Porém a maioria dos retornos disponíveis vem diretamente do Starlette. O mesmo com `status`.
## OpenAPI e documentação da API
Se você retorna códigos de status adicionais e retornos diretamente, eles não serão incluídos no esquema do OpenAPI (a documentação da API), porque o FastAPI não tem como saber de antemão o que será retornado.
Mas você pode documentar isso no seu código, utilizando: [Retornos Adicionais](additional-responses.md){.internal-link target=_blank}.

138
docs/pt/docs/advanced/advanced-dependencies.md

@ -0,0 +1,138 @@
# Dependências avançadas
## Dependências parametrizadas
Todas as dependências que vimos até agora são funções ou classes fixas.
Mas podem ocorrer casos onde você deseja ser capaz de definir parâmetros na dependência, sem ter a necessidade de declarar diversas funções ou classes.
Vamos imaginar que queremos ter uma dependência que verifica se o parâmetro de consulta `q` possui um valor fixo.
Porém nós queremos poder parametrizar o conteúdo fixo.
## Uma instância "chamável"
Em Python existe uma maneira de fazer com que uma instância de uma classe seja um "chamável".
Não propriamente a classe (que já é um chamável), mas a instância desta classe.
Para fazer isso, nós declaramos o método `__call__`:
=== "Python 3.9+"
```Python hl_lines="12"
{!> ../../../docs_src/dependencies/tutorial011_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="11"
{!> ../../../docs_src/dependencies/tutorial011_an.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip "Dica"
Prefira utilizar a versão `Annotated` se possível.
```Python hl_lines="10"
{!> ../../../docs_src/dependencies/tutorial011.py!}
```
Neste caso, o `__call__` é o que o **FastAPI** utilizará para verificar parâmetros adicionais e sub dependências, e isso é o que será chamado para passar o valor ao parâmetro na sua *função de operação de rota* posteriormente.
## Parametrizar a instância
E agora, nós podemos utilizar o `__init__` para declarar os parâmetros da instância que podemos utilizar para "parametrizar" a dependência:
=== "Python 3.9+"
```Python hl_lines="9"
{!> ../../../docs_src/dependencies/tutorial011_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="8"
{!> ../../../docs_src/dependencies/tutorial011_an.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip "Dica"
Prefira utilizar a versão `Annotated` se possível.
```Python hl_lines="7"
{!> ../../../docs_src/dependencies/tutorial011.py!}
```
Neste caso, o **FastAPI** nunca tocará ou se importará com o `__init__`, nós vamos utilizar diretamente em nosso código.
## Crie uma instância
Nós poderíamos criar uma instância desta classe com:
=== "Python 3.9+"
```Python hl_lines="18"
{!> ../../../docs_src/dependencies/tutorial011_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="17"
{!> ../../../docs_src/dependencies/tutorial011_an.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip "Dica"
Prefira utilizar a versão `Annotated` se possível.
```Python hl_lines="16"
{!> ../../../docs_src/dependencies/tutorial011.py!}
```
E deste modo nós podemos "parametrizar" a nossa dependência, que agora possui `"bar"` dentro dele, como o atributo `checker.fixed_content`.
## Utilize a instância como dependência
Então, nós podemos utilizar este `checker` em um `Depends(checker)`, no lugar de `Depends(FixedContentQueryChecker)`, porque a dependência é a instância, `checker`, e não a própria classe.
E quando a dependência for resolvida, o **FastAPI** chamará este `checker` como:
```Python
checker(q="somequery")
```
...e passar o que quer que isso retorne como valor da dependência em nossa *função de operação de rota* como o parâmetro `fixed_content_included`:
=== "Python 3.9+"
```Python hl_lines="22"
{!> ../../../docs_src/dependencies/tutorial011_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="21"
{!> ../../../docs_src/dependencies/tutorial011_an.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip "Dica"
Prefira utilizar a versão `Annotated` se possível.
```Python hl_lines="20"
{!> ../../../docs_src/dependencies/tutorial011.py!}
```
!!! tip "Dica"
Tudo isso parece não ser natural. E pode não estar muito claro ou aparentar ser útil ainda.
Estes exemplos são intencionalmente simples, porém mostram como tudo funciona.
Nos capítulos sobre segurança, existem funções utilitárias que são implementadas desta maneira.
Se você entendeu tudo isso, você já sabe como essas funções utilitárias para segurança funcionam por debaixo dos panos.

485
docs/pt/docs/advanced/settings.md

@ -0,0 +1,485 @@
# Configurações e Variáveis de Ambiente
Em muitos casos a sua aplicação pode precisar de configurações externas, como chaves secretas, credenciais de banco de dados, credenciais para serviços de email, etc.
A maioria dessas configurações é variável (podem mudar), como URLs de bancos de dados. E muitas delas podem conter dados sensíveis, como tokens secretos.
Por isso é comum prover essas configurações como variáveis de ambiente que são utilizidas pela aplicação.
## Variáveis de Ambiente
!!! dica
Se você já sabe o que são variáveis de ambiente e como utilizá-las, sinta-se livre para avançar para o próximo tópico.
Uma <a href="https://pt.wikipedia.org/wiki/Variável_de_ambiente" class="external-link" target="_blank">variável de ambiente</a> (abreviada em inglês para "env var") é uma variável definida fora do código Python, no sistema operacional, e pode ser lida pelo seu código Python (ou por outros programas).
Você pode criar e utilizar variáveis de ambiente no terminal, sem precisar utilizar Python:
=== "Linux, macOS, Windows Bash"
<div class="termy">
```console
// Você pode criar uma env var MY_NAME usando
$ export MY_NAME="Wade Wilson"
// E utilizá-la em outros programas, como
$ echo "Hello $MY_NAME"
Hello Wade Wilson
```
</div>
=== "Windows PowerShell"
<div class="termy">
```console
// Criando env var MY_NAME
$ $Env:MY_NAME = "Wade Wilson"
// Usando em outros programas, como
$ echo "Hello $Env:MY_NAME"
Hello Wade Wilson
```
</div>
### Lendo variáveis de ambiente com Python
Você também pode criar variáveis de ambiente fora do Python, no terminal (ou com qualquer outro método), e realizar a leitura delas no Python.
Por exemplo, você pode definir um arquivo `main.py` com o seguinte código:
```Python hl_lines="3"
import os
name = os.getenv("MY_NAME", "World")
print(f"Hello {name} from Python")
```
!!! dica
O segundo parâmetro em <a href="https://docs.python.org/3.8/library/os.html#os.getenv" class="external-link" target="_blank">`os.getenv()`</a> é o valor padrão para o retorno.
Se nenhum valor for informado, `None` é utilizado por padrão, aqui definimos `"World"` como o valor padrão a ser utilizado.
E depois você pode executar esse arquivo:
<div class="termy">
```console
// Aqui ainda não definimos a env var
$ python main.py
// Por isso obtemos o valor padrão
Hello World from Python
// Mas se definirmos uma variável de ambiente primeiro
$ export MY_NAME="Wade Wilson"
// E executarmos o programa novamente
$ python main.py
// Agora ele pode ler a variável de ambiente
Hello Wade Wilson from Python
```
</div>
Como variáveis de ambiente podem ser definidas fora do código da aplicação, mas acessadas pela aplicação, e não precisam ser armazenadas (versionadas com `git`) junto dos outros arquivos, é comum utilizá-las para guardar configurações.
Você também pode criar uma variável de ambiente específica para uma invocação de um programa, que é acessível somente para esse programa, e somente enquanto ele estiver executando.
Para fazer isso, crie a variável imediatamente antes de iniciar o programa, na mesma linha:
<div class="termy">
```console
// Criando uma env var MY_NAME na mesma linha da execução do programa
$ MY_NAME="Wade Wilson" python main.py
// Agora a aplicação consegue ler a variável de ambiente
Hello Wade Wilson from Python
// E a variável deixa de existir após isso
$ python main.py
Hello World from Python
```
</div>
!!! dica
Você pode ler mais sobre isso em: <a href="https://12factor.net/pt_br/config" class="external-link" target="_blank">The Twelve-Factor App: Configurações</a>.
### Tipagem e Validação
Essas variáveis de ambiente suportam apenas strings, por serem externas ao Python e por que precisam ser compatíveis com outros programas e o resto do sistema (e até mesmo com outros sistemas operacionais, como Linux, Windows e macOS).
Isso significa que qualquer valor obtido de uma variável de ambiente em Python terá o tipo `str`, e qualquer conversão para um tipo diferente ou validação deve ser realizada no código.
## Pydantic `Settings`
Por sorte, o Pydantic possui uma funcionalidade para lidar com essas configurações vindas de variáveis de ambiente utilizando <a href="https://docs.pydantic.dev/latest/usage/pydantic_settings/" class="external-link" target="_blank">Pydantic: Settings management</a>.
### Instalando `pydantic-settings`
Primeiro, instale o pacote `pydantic-settings`:
<div class="termy">
```console
$ pip install pydantic-settings
---> 100%
```
</div>
Ele também está incluído no fastapi quando você instala com a opção `all`:
<div class="termy">
```console
$ pip install "fastapi[all]"
---> 100%
```
</div>
!!! info
Na v1 do Pydantic ele estava incluído no pacote principal. Agora ele está distribuido como um pacote independente para que você possa optar por instalar ou não caso você não precise dessa funcionalidade.
### Criando o objeto `Settings`
Importe a classe `BaseSettings` do Pydantic e crie uma nova subclasse, de forma parecida com um modelo do Pydantic.
Os atributos da classe são declarados com anotações de tipo, e possíveis valores padrão, da mesma maneira que os modelos do Pydantic.
Você pode utilizar todas as ferramentas e funcionalidades de validação que são utilizadas nos modelos do Pydantic, como tipos de dados diferentes e validações adicionei com `Field()`.
=== "Pydantic v2"
```Python hl_lines="2 5-8 11"
{!> ../../../docs_src/settings/tutorial001.py!}
```
=== "Pydantic v1"
!!! Info
Na versão 1 do Pydantic você importaria `BaseSettings` diretamente do módulo `pydantic` em vez do módulo `pydantic_settings`.
```Python hl_lines="2 5-8 11"
{!> ../../../docs_src/settings/tutorial001_pv1.py!}
```
!!! dica
Se você quiser algo pronto para copiar e colar na sua aplicação, não use esse exemplo, mas sim o exemplo abaixo.
Portanto, quando você cria uma instância da classe `Settings` (nesse caso, o objeto `settings`), o Pydantic lê as variáveis de ambiente sem diferenciar maiúsculas e minúsculas, por isso, uma variável maiúscula `APP_NAME` será usada para o atributo `app_name`.
Depois ele irá converter e validar os dados. Assim, quando você utilizar aquele objeto `settings`, os dados terão o tipo que você declarou (e.g. `items_per_user` será do tipo `int`).
### Usando o objeto `settings`
Depois, Você pode utilizar o novo objeto `settings` na sua aplicação:
```Python hl_lines="18-20"
{!../../../docs_src/settings/tutorial001.py!}
```
### Executando o servidor
No próximo passo, você pode inicializar o servidor passando as configurações em forma de variáveis de ambiente, por exemplo, você poderia definir `ADMIN_EMAIL` e `APP_NAME` da seguinte forma:
<div class="termy">
```console
$ ADMIN_EMAIL="[email protected]" APP_NAME="ChimichangApp" fastapi run main.py
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
!!! dica
Para definir múltiplas variáveis de ambiente para um único comando basta separá-las utilizando espaços, e incluir todas elas antes do comando.
Assim, o atributo `admin_email` seria definido como `"[email protected]"`.
`app_name` seria `"ChimichangApp"`.
E `items_per_user` manteria o valor padrão de `50`.
## Configurações em um módulo separado
Você também pode incluir essas configurações em um arquivo de um módulo separado como visto em [Bigger Applications - Multiple Files](../tutorial/bigger-applications.md){.internal-link target=\_blank}.
Por exemplo, você pode adicionar um arquivo `config.py` com:
```Python
{!../../../docs_src/settings/app01/config.py!}
```
E utilizar essa configuração em `main.py`:
```Python hl_lines="3 11-13"
{!../../../docs_src/settings/app01/main.py!}
```
!!! dica
Você também precisa incluir um arquivo `__init__.py` como visto em [Bigger Applications - Multiple Files](../tutorial/bigger-applications.md){.internal-link target=\_blank}.
## Configurações em uma dependência
Em certas ocasiões, pode ser útil fornecer essas configurações a partir de uma dependência, em vez de definir um objeto global `settings` que é utilizado em toda a aplicação.
Isso é especialmente útil durante os testes, já que é bastante simples sobrescrever uma dependência com suas configurações personalizadas.
### O arquivo de configuração
Baseando-se no exemplo anterior, seu arquivo `config.py` seria parecido com isso:
```Python hl_lines="10"
{!../../../docs_src/settings/app02/config.py!}
```
Perceba que dessa vez não criamos uma instância padrão `settings = Settings()`.
### O arquivo principal da aplicação
Agora criamos a dependência que retorna um novo objeto `config.Settings()`.
=== "Python 3.9+"
```Python hl_lines="6 12-13"
{!> ../../../docs_src/settings/app02_an_py39/main.py!}
```
=== "Python 3.8+"
```Python hl_lines="6 12-13"
{!> ../../../docs_src/settings/app02_an/main.py!}
```
=== "Python 3.8+ non-Annotated"
!!! dica
Utilize a versão com `Annotated` se possível.
```Python hl_lines="5 11-12"
{!> ../../../docs_src/settings/app02/main.py!}
```
!!! dica
Vamos discutir sobre `@lru_cache` logo mais.
Por enquanto, você pode considerar `get_settings()` como uma função normal.
E então podemos declarar essas configurações como uma dependência na função de operação da rota e utilizar onde for necessário.
=== "Python 3.9+"
```Python hl_lines="17 19-21"
{!> ../../../docs_src/settings/app02_an_py39/main.py!}
```
=== "Python 3.8+"
```Python hl_lines="17 19-21"
{!> ../../../docs_src/settings/app02_an/main.py!}
```
=== "Python 3.8+ non-Annotated"
!!! dica
Utilize a versão com `Annotated` se possível.
```Python hl_lines="16 18-20"
{!> ../../../docs_src/settings/app02/main.py!}
```
### Configurações e testes
Então seria muito fácil fornecer uma configuração diferente durante a execução dos testes sobrescrevendo a dependência de `get_settings`:
```Python hl_lines="9-10 13 21"
{!../../../docs_src/settings/app02/test_main.py!}
```
Na sobrescrita da dependência, definimos um novo valor para `admin_email` quando instanciamos um novo objeto `Settings`, e então retornamos esse novo objeto.
Após isso, podemos testar se o valor está sendo utilizado.
## Lendo um arquivo `.env`
Se você tiver muitas configurações que variem bastante, talvez em ambientes distintos, pode ser útil colocá-las em um arquivo e depois lê-las como se fossem variáveis de ambiente.
Essa prática é tão comum que possui um nome, essas variáveis de ambiente normalmente são colocadas em um arquivo `.env`, e esse arquivo é chamado de "dotenv".
!!! dica
Um arquivo iniciando com um ponto final (`.`) é um arquivo oculto em sistemas baseados em Unix, como Linux e MacOS.
Mas um arquivo dotenv não precisa ter esse nome exato.
Pydantic suporta a leitura desses tipos de arquivos utilizando uma biblioteca externa. Você pode ler mais em <a href="https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support" class="external-link" target="_blank">Pydantic Settings: Dotenv (.env) support</a>.
!!! dica
Para que isso funcione você precisa executar `pip install python-dotenv`.
### O arquivo `.env`
Você pode definir um arquivo `.env` com o seguinte conteúdo:
```bash
ADMIN_EMAIL="[email protected]"
APP_NAME="ChimichangApp"
```
### Obtendo configurações do `.env`
E então adicionar o seguinte código em `config.py`:
=== "Pydantic v2"
```Python hl_lines="9"
{!> ../../../docs_src/settings/app03_an/config.py!}
```
!!! dica
O atributo `model_config` é usado apenas para configuração do Pydantic. Você pode ler mais em <a href="https://docs.pydantic.dev/latest/usage/model_config/" class="external-link" target="_blank">Pydantic Model Config</a>.
=== "Pydantic v1"
```Python hl_lines="9-10"
{!> ../../../docs_src/settings/app03_an/config_pv1.py!}
```
!!! dica
A classe `Config` é usada apenas para configuração do Pydantic. Você pode ler mais em <a href="https://docs.pydantic.dev/1.10/usage/model_config/" class="external-link" target="_blank">Pydantic Model Config</a>.
!!! info
Na versão 1 do Pydantic a configuração é realizada por uma classe interna `Config`, na versão 2 do Pydantic isso é feito com o atributo `model_config`. Esse atributo recebe um `dict`, para utilizar o autocomplete e checagem de erros do seu editor de texto você pode importar e utilizar `SettingsConfigDict` para definir esse `dict`.
Aqui definimos a configuração `env_file` dentro da classe `Settings` do Pydantic, e definimos o valor como o nome do arquivo dotenv que queremos utilizar.
### Declarando `Settings` apenas uma vez com `lru_cache`
Ler o conteúdo de um arquivo em disco normalmente é uma operação custosa (lenta), então você provavelmente quer fazer isso apenas um vez e reutilizar o mesmo objeto settings depois, em vez de ler os valores a cada requisição.
Mas cada vez que fazemos:
```Python
Settings()
```
um novo objeto `Settings` é instanciado, e durante a instanciação, o arquivo `.env` é lido novamente.
Se a função da dependência fosse apenas:
```Python
def get_settings():
return Settings()
```
Iriamos criar um novo objeto a cada requisição, e estaríamos lendo o arquivo `.env` a cada requisição. ⚠️
Mas como estamos utilizando o decorador `@lru_cache` acima, o objeto `Settings` é criado apenas uma vez, na primeira vez que a função é chamada. ✔️
=== "Python 3.9+"
```Python hl_lines="1 11"
{!> ../../../docs_src/settings/app03_an_py39/main.py!}
```
=== "Python 3.8+"
```Python hl_lines="1 11"
{!> ../../../docs_src/settings/app03_an/main.py!}
```
=== "Python 3.8+ non-Annotated"
!!! dica
Utilize a versão com `Annotated` se possível.
```Python hl_lines="1 10"
{!> ../../../docs_src/settings/app03/main.py!}
```
Dessa forma, todas as chamadas da função `get_settings()` nas dependências das próximas requisições, em vez de executar o código interno de `get_settings()` e instanciar um novo objeto `Settings`, irão retornar o mesmo objeto que foi retornado na primeira chamada, de novo e de novo.
#### Detalhes Técnicos de `lru_cache`
`@lru_cache` modifica a função decorada para retornar o mesmo valor que foi retornado na primeira vez, em vez de calculá-lo novamente, executando o código da função toda vez.
Assim, a função abaixo do decorador é executada uma única vez para cada combinação dos argumentos passados. E os valores retornados para cada combinação de argumentos são sempre reutilizados para cada nova chamada da função com a mesma combinação de argumentos.
Por exemplo, se você definir uma função:
```Python
@lru_cache
def say_hi(name: str, salutation: str = "Ms."):
return f"Hello {salutation} {name}"
```
Seu programa poderia executar dessa forma:
```mermaid
sequenceDiagram
participant code as Código
participant function as say_hi()
participant execute as Executar Função
rect rgba(0, 255, 0, .1)
code ->> function: say_hi(name="Camila")
function ->> execute: executar código da função
execute ->> code: retornar o resultado
end
rect rgba(0, 255, 255, .1)
code ->> function: say_hi(name="Camila")
function ->> code: retornar resultado armazenado
end
rect rgba(0, 255, 0, .1)
code ->> function: say_hi(name="Rick")
function ->> execute: executar código da função
execute ->> code: retornar o resultado
end
rect rgba(0, 255, 0, .1)
code ->> function: say_hi(name="Rick", salutation="Mr.")
function ->> execute: executar código da função
execute ->> code: retornar o resultado
end
rect rgba(0, 255, 255, .1)
code ->> function: say_hi(name="Rick")
function ->> code: retornar resultado armazenado
end
rect rgba(0, 255, 255, .1)
code ->> function: say_hi(name="Camila")
function ->> code: retornar resultado armazenado
end
```
No caso da nossa dependência `get_settings()`, a função não recebe nenhum argumento, então ela sempre retorna o mesmo valor.
Dessa forma, ela se comporta praticamente como uma variável global, mas ao ser utilizada como uma função de uma dependência, pode facilmente ser sobrescrita durante os testes.
`@lru_cache` é definido no módulo `functools` que faz parte da biblioteca padrão do Python, você pode ler mais sobre esse decorador no link <a href="https://docs.python.org/3/library/functools.html#functools.lru_cache" class="external-link" target="_blank">Python Docs sobre `@lru_cache`</a>.
## Recapitulando
Você pode usar o módulo Pydantic Settings para gerenciar as configurações de sua aplicação, utilizando todo o poder dos modelos Pydantic.
- Utilizar dependências simplifica os testes.
- Você pode utilizar arquivos .env junto das configurações do Pydantic.
- Utilizar o decorador `@lru_cache` evita que o arquivo .env seja lido de novo e de novo para cada requisição, enquanto permite que você sobrescreva durante os testes.

11
docs/pt/docs/how-to/index.md

@ -0,0 +1,11 @@
# Como Fazer - Exemplos Práticos
Aqui você encontrará diferentes exemplos práticos ou tutoriais de "como fazer" para vários tópicos.
A maioria dessas ideias será mais ou menos **independente**, e na maioria dos casos você só precisará estudá-las se elas se aplicarem diretamente ao **seu projeto**.
Se algo parecer interessante e útil para o seu projeto, vá em frente e dê uma olhada. Caso contrário, você pode simplesmente ignorá-lo.
!!! tip
Se você deseja **aprender FastAPI** de forma estruturada (recomendado), leia capítulo por capítulo [Tutorial - Guia de Usuário](../tutorial/index.md){.internal-link target=_blank} em vez disso.

497
docs/pt/docs/tutorial/dependencies/classes-as-dependencies.md

@ -0,0 +1,497 @@
# Classes como Dependências
Antes de nos aprofundarmos no sistema de **Injeção de Dependência**, vamos melhorar o exemplo anterior.
## `dict` do exemplo anterior
No exemplo anterior, nós retornávamos um `dict` da nossa dependência ("injetável"):
=== "Python 3.10+"
```Python hl_lines="9"
{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="11"
{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="12"
{!> ../../../docs_src/dependencies/tutorial001_an.py!}
```
=== "Python 3.10+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python hl_lines="7"
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python hl_lines="11"
{!> ../../../docs_src/dependencies/tutorial001.py!}
```
Mas assim obtemos um `dict` como valor do parâmetro `commons` na *função de operação de rota*.
E sabemos que editores de texto não têm como oferecer muitas funcionalidades (como sugestões automáticas) para objetos do tipo `dict`, por que não há como eles saberem o tipo das chaves e dos valores.
Podemos fazer melhor...
## O que caracteriza uma dependência
Até agora você apenas viu dependências declaradas como funções.
Mas essa não é a única forma de declarar dependências (mesmo que provavelmente seja a mais comum).
O fator principal para uma dependência é que ela deve ser "chamável"
Um objeto "chamável" em Python é qualquer coisa que o Python possa "chamar" como uma função
Então se você tiver um objeto `alguma_coisa` (que pode *não* ser uma função) que você possa "chamar" (executá-lo) dessa maneira:
```Python
something()
```
ou
```Python
something(some_argument, some_keyword_argument="foo")
```
Então esse objeto é um "chamável".
## Classes como dependências
Você deve ter percebido que para criar um instância de uma classe em Python, a mesma sintaxe é utilizada.
Por exemplo:
```Python
class Cat:
def __init__(self, name: str):
self.name = name
fluffy = Cat(name="Mr Fluffy")
```
Nesse caso, `fluffy` é uma instância da classe `Cat`.
E para criar `fluffy`, você está "chamando" `Cat`.
Então, uma classe Python também é "chamável".
Então, no **FastAPI**, você pode utilizar uma classe Python como uma dependência.
O que o FastAPI realmente verifica, é se a dependência é algo chamável (função, classe, ou outra coisa) e os parâmetros que foram definidos.
Se você passar algo "chamável" como uma dependência do **FastAPI**, o framework irá analisar os parâmetros desse "chamável" e processá-los da mesma forma que os parâmetros de uma *função de operação de rota*. Incluindo as sub-dependências.
Isso também se aplica a objetos chamáveis que não recebem nenhum parâmetro. Da mesma forma que uma *função de operação de rota* sem parâmetros.
Então, podemos mudar o "injetável" na dependência `common_parameters` acima para a classe `CommonQueryParams`:
=== "Python 3.10+"
```Python hl_lines="11-15"
{!> ../../../docs_src/dependencies/tutorial002_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="11-15"
{!> ../../../docs_src/dependencies/tutorial002_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="12-16"
{!> ../../../docs_src/dependencies/tutorial002_an.py!}
```
=== "Python 3.10+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python hl_lines="9-13"
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python hl_lines="11-15"
{!> ../../../docs_src/dependencies/tutorial002.py!}
```
Observe o método `__init__` usado para criar uma instância da classe:
=== "Python 3.10+"
```Python hl_lines="12"
{!> ../../../docs_src/dependencies/tutorial002_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="12"
{!> ../../../docs_src/dependencies/tutorial002_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="13"
{!> ../../../docs_src/dependencies/tutorial002_an.py!}
```
=== "Python 3.10+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python hl_lines="10"
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python hl_lines="12"
{!> ../../../docs_src/dependencies/tutorial002.py!}
```
...ele possui os mesmos parâmetros que nosso `common_parameters` anterior:
=== "Python 3.10+"
```Python hl_lines="8"
{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="9"
{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="10"
{!> ../../../docs_src/dependencies/tutorial001_an.py!}
```
=== "Python 3.10+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python hl_lines="6"
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python hl_lines="9"
{!> ../../../docs_src/dependencies/tutorial001.py!}
```
Esses parâmetros são utilizados pelo **FastAPI** para "definir" a dependência.
Em ambos os casos teremos:
* Um parâmetro de consulta `q` opcional do tipo `str`.
* Um parâmetro de consulta `skip` do tipo `int`, com valor padrão `0`.
* Um parâmetro de consulta `limit` do tipo `int`, com valor padrão `100`.
Os dados serão convertidos, validados, documentados no esquema da OpenAPI e etc nos dois casos.
## Utilizando
Agora você pode declarar sua dependência utilizando essa classe.
=== "Python 3.10+"
```Python hl_lines="19"
{!> ../../../docs_src/dependencies/tutorial002_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="19"
{!> ../../../docs_src/dependencies/tutorial002_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="20"
{!> ../../../docs_src/dependencies/tutorial002_an.py!}
```
=== "Python 3.10+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python hl_lines="17"
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python hl_lines="19"
{!> ../../../docs_src/dependencies/tutorial002.py!}
```
O **FastAPI** chama a classe `CommonQueryParams`. Isso cria uma "instância" dessa classe e é a instância que será passada para o parâmetro `commons` na sua função.
## Anotações de Tipo vs `Depends`
Perceba como escrevemos `CommonQueryParams` duas vezes no código abaixo:
=== "Python 3.8+"
```Python
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
```
=== "Python 3.8+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python
commons: CommonQueryParams = Depends(CommonQueryParams)
```
O último `CommonQueryParams`, em:
```Python
... Depends(CommonQueryParams)
```
...é o que o **FastAPI** irá realmente usar para saber qual é a dependência.
É a partir dele que o FastAPI irá extrair os parâmetros passados e será o que o FastAPI irá realmente chamar.
---
Nesse caso, o primeiro `CommonQueryParams`, em:
=== "Python 3.8+"
```Python
commons: Annotated[CommonQueryParams, ...
```
=== "Python 3.8+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python
commons: CommonQueryParams ...
```
...não tem nenhum signficado especial para o **FastAPI**. O FastAPI não irá utilizá-lo para conversão dos dados, validação, etc (já que ele utiliza `Depends(CommonQueryParams)` para isso).
Na verdade você poderia escrever apenas:
=== "Python 3.8+"
```Python
commons: Annotated[Any, Depends(CommonQueryParams)]
```
=== "Python 3.8+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python
commons = Depends(CommonQueryParams)
```
...como em:
=== "Python 3.10+"
```Python hl_lines="19"
{!> ../../../docs_src/dependencies/tutorial003_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="19"
{!> ../../../docs_src/dependencies/tutorial003_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="20"
{!> ../../../docs_src/dependencies/tutorial003_an.py!}
```
=== "Python 3.10+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python hl_lines="17"
{!> ../../../docs_src/dependencies/tutorial003_py310.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python hl_lines="19"
{!> ../../../docs_src/dependencies/tutorial003.py!}
```
Mas declarar o tipo é encorajado por que é a forma que o seu editor de texto sabe o que será passado como valor do parâmetro `commons`.
<img src="/img/tutorial/dependencies/image02.png">
## Pegando um Atalho
Mas você pode ver que temos uma repetição do código neste exemplo, escrevendo `CommonQueryParams` duas vezes:
=== "Python 3.8+"
```Python
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
```
=== "Python 3.8+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python
commons: CommonQueryParams = Depends(CommonQueryParams)
```
O **FastAPI** nos fornece um atalho para esses casos, onde a dependência é *especificamente* uma classe que o **FastAPI** irá "chamar" para criar uma instância da própria classe.
Para esses casos específicos, você pode fazer o seguinte:
Em vez de escrever:
=== "Python 3.8+"
```Python
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
```
=== "Python 3.8+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python
commons: CommonQueryParams = Depends(CommonQueryParams)
```
...escreva:
=== "Python 3.8+"
```Python
commons: Annotated[CommonQueryParams, Depends()]
```
=== "Python 3.8 non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python
commons: CommonQueryParams = Depends()
```
Você declara a dependência como o tipo do parâmetro, e utiliza `Depends()` sem nenhum parâmetro, em vez de ter que escrever a classe *novamente* dentro de `Depends(CommonQueryParams)`.
O mesmo exemplo ficaria então dessa forma:
=== "Python 3.10+"
```Python hl_lines="19"
{!> ../../../docs_src/dependencies/tutorial004_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="19"
{!> ../../../docs_src/dependencies/tutorial004_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="20"
{!> ../../../docs_src/dependencies/tutorial004_an.py!}
```
=== "Python 3.10+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python hl_lines="17"
{!> ../../../docs_src/dependencies/tutorial004_py310.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python hl_lines="19"
{!> ../../../docs_src/dependencies/tutorial004.py!}
```
...e o **FastAPI** saberá o que fazer.
!!! tip "Dica"
Se isso parece mais confuso do que útil, não utilize, você não *precisa* disso.
É apenas um atalho. Por que o **FastAPI** se preocupa em ajudar a minimizar a repetição de código.

353
docs/pt/docs/tutorial/dependencies/index.md

@ -0,0 +1,353 @@
# Dependências
O **FastAPI** possui um poderoso, mas intuitivo sistema de **<abbr title="também conhecidos como, recursos, provedores, serviços, injetáveis">Injeção de Dependência</abbr>**.
Esse sistema foi pensado para ser fácil de usar, e permitir que qualquer desenvolvedor possa integrar facilmente outros componentes ao **FastAPI**.
## O que é "Injeção de Dependência"
**"Injeção de Dependência"** no mundo da programação significa, que existe uma maneira de declarar no seu código (nesse caso, suas *funções de operação de rota*) para declarar as coisas que ele precisa para funcionar e que serão utilizadas: "dependências".
Então, esse sistema (nesse caso o **FastAPI**) se encarrega de fazer o que for preciso para fornecer essas dependências para o código ("injetando" as dependências).
Isso é bastante útil quando você precisa:
* Definir uma lógica compartilhada (mesmo formato de código repetidamente).
* Compartilhar conexões com banco de dados.
* Aplicar regras de segurança, autenticação, papéis de usuários, etc.
* E muitas outras coisas...
Tudo isso, enquanto minimizamos a repetição de código.
## Primeiros passos
Vamos ver um exemplo simples. Tão simples que não será muito útil, por enquanto.
Mas dessa forma podemos focar em como o sistema de **Injeção de Dependência** funciona.
### Criando uma dependência, ou "injetável"
Primeiro vamos focar na dependência.
Ela é apenas uma função que pode receber os mesmos parâmetros de uma *função de operação de rota*:
=== "Python 3.10+"
```Python hl_lines="8-9"
{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="8-11"
{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="9-12"
{!> ../../../docs_src/dependencies/tutorial001_an.py!}
```
=== "Python 3.10+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python hl_lines="6-7"
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python hl_lines="8-11"
{!> ../../../docs_src/dependencies/tutorial001.py!}
```
E pronto.
**2 linhas**.
E com a mesma forma e estrutura de todas as suas *funções de operação de rota*.
Você pode pensar nela como uma *função de operação de rota* sem o "decorador" (sem a linha `@app.get("/some-path")`).
E com qualquer retorno que você desejar.
Neste caso, a dependência espera por:
* Um parâmetro de consulta opcional `q` do tipo `str`.
* Um parâmetro de consulta opcional `skip` do tipo `int`, e igual a `0` por padrão.
* Um parâmetro de consulta opcional `limit` do tipo `int`, e igual a `100` por padrão.
E então retorna um `dict` contendo esses valores.
!!! info "Informação"
FastAPI passou a suportar a notação `Annotated` (e começou a recomendá-la) na versão 0.95.0.
Se você utiliza uma versão anterior, ocorrerão erros ao tentar utilizar `Annotated`.
Certifique-se de [Atualizar a versão do FastAPI](../../deployment/versions.md#atualizando-as-versoes-do-fastapi){.internal-link target=_blank} para pelo menos 0.95.1 antes de usar `Annotated`.
### Importando `Depends`
=== "Python 3.10+"
```Python hl_lines="3"
{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="3"
{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="3"
{!> ../../../docs_src/dependencies/tutorial001_an.py!}
```
=== "Python 3.10+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python hl_lines="1"
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python hl_lines="3"
{!> ../../../docs_src/dependencies/tutorial001.py!}
```
### Declarando a dependência, no "dependente"
Da mesma forma que você utiliza `Body`, `Query`, etc. Como parâmetros de sua *função de operação de rota*, utilize `Depends` com um novo parâmetro:
=== "Python 3.10+"
```Python hl_lines="13 18"
{!> ../../../docs_src/dependencies/tutorial001_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="15 20"
{!> ../../../docs_src/dependencies/tutorial001_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="16 21"
{!> ../../../docs_src/dependencies/tutorial001_an.py!}
```
=== "Python 3.10+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python hl_lines="11 16"
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip "Dica"
Utilize a versão com `Annotated` se possível.
```Python hl_lines="15 20"
{!> ../../../docs_src/dependencies/tutorial001.py!}
```
Ainda que `Depends` seja utilizado nos parâmetros da função da mesma forma que `Body`, `Query`, etc, `Depends` funciona de uma forma um pouco diferente.
Você fornece um único parâmetro para `Depends`.
Esse parâmetro deve ser algo como uma função.
Você **não chama a função** diretamente (não adicione os parênteses no final), apenas a passe como parâmetro de `Depends()`.
E essa função vai receber os parâmetros da mesma forma que uma *função de operação de rota*.
!!! tip "Dica"
Você verá quais outras "coisas", além de funções, podem ser usadas como dependências no próximo capítulo.
Sempre que uma nova requisição for realizada, o **FastAPI** se encarrega de:
* Chamar sua dependência ("injetável") com os parâmetros corretos.
* Obter o resultado da função.
* Atribuir esse resultado para o parâmetro em sua *função de operação de rota*.
```mermaid
graph TB
common_parameters(["common_parameters"])
read_items["/items/"]
read_users["/users/"]
common_parameters --> read_items
common_parameters --> read_users
```
Assim, você escreve um código compartilhado apenas uma vez e o **FastAPI** se encarrega de chamá-lo em suas *operações de rota*.
!!! check "Checando"
Perceba que você não precisa criar uma classe especial e enviar a dependência para algum outro lugar em que o **FastAPI** a "registre" ou realize qualquer operação similar.
Você apenas envia para `Depends` e o **FastAPI** sabe como fazer o resto.
## Compartilhando dependências `Annotated`
Nos exemplos acima, você pode ver que existe uma pequena **duplicação de código**.
Quando você precisa utilizar a dependência `common_parameters()`, você precisa escrever o parâmetro inteiro com uma anotação de tipo e `Depends()`:
```Python
commons: Annotated[dict, Depends(common_parameters)]
```
Mas como estamos utilizando `Annotated`, podemos guardar esse valor `Annotated` em uma variável e utilizá-la em múltiplos locais:
=== "Python 3.10+"
```Python hl_lines="12 16 21"
{!> ../../../docs_src/dependencies/tutorial001_02_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="14 18 23"
{!> ../../../docs_src/dependencies/tutorial001_02_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="15 19 24"
{!> ../../../docs_src/dependencies/tutorial001_02_an.py!}
```
!!! tip "Dica"
Isso é apenas Python padrão, essa funcionalidade é chamada de "type alias", e na verdade não é específica ao **FastAPI**.
Mas como o **FastAPI** se baseia em convenções do Python, incluindo `Annotated`, você pode incluir esse truque no seu código. 😎
As dependências continuarão funcionando como esperado, e a **melhor parte** é que a **informação sobre o tipo é preservada**, o que signfica que seu editor de texto ainda irá incluir **preenchimento automático**, **visualização de erros**, etc. O mesmo vale para ferramentas como `mypy`.
Isso é especialmente útil para uma **base de código grande** onde **as mesmas dependências** são utilizadas repetidamente em **muitas *operações de rota***.
## `Async` ou não, eis a questão
Como as dependências também serão chamadas pelo **FastAPI** (da mesma forma que *funções de operação de rota*), as mesmas regras se aplicam ao definir suas funções.
Você pode utilizar `async def` ou apenas `def`.
E você pode declarar dependências utilizando `async def` dentro de *funções de operação de rota* definidas com `def`, ou declarar dependências com `def` e utilizar dentro de *funções de operação de rota* definidas com `async def`, etc.
Não faz diferença. O **FastAPI** sabe o que fazer.
!!! note "Nota"
Caso você não conheça, veja em [Async: *"Com Pressa?"*](../../async.md#com-pressa){.internal-link target=_blank} a sessão acerca de `async` e `await` na documentação.
## Integrando com OpenAPI
Todas as declarações de requisições, validações e requisitos para suas dependências (e sub-dependências) serão integradas em um mesmo esquema OpenAPI.
Então, a documentação interativa também terá toda a informação sobre essas dependências:
<img src="/img/tutorial/dependencies/image01.png">
## Caso de Uso Simples
Se você parar para ver, *funções de operação de rota* são declaradas para serem usadas sempre que uma *rota* e uma *operação* se encaixam, e então o **FastAPI** se encarrega de chamar a função correspondente com os argumentos corretos, extraindo os dados da requisição.
Na verdade, todos (ou a maioria) dos frameworks web funcionam da mesma forma.
Você nunca chama essas funções diretamente. Elas são chamadas pelo framework utilizado (nesse caso, **FastAPI**).
Com o Sistema de Injeção de Dependência, você também pode informar ao **FastAPI** que sua *função de operação de rota* também "depende" em algo a mais que deve ser executado antes de sua *função de operação de rota*, e o **FastAPI** se encarrega de executar e "injetar" os resultados.
Outros termos comuns para essa mesma ideia de "injeção de dependência" são:
* recursos
* provedores
* serviços
* injetáveis
* componentes
## Plug-ins em **FastAPI**
Integrações e "plug-ins" podem ser construídos com o sistema de **Injeção de Dependência**. Mas na verdade, **não há necessidade de criar "plug-ins"**, já que utilizando dependências é possível declarar um número infinito de integrações e interações que se tornam disponíveis para as suas *funções de operação de rota*.
E as dependências pode ser criadas de uma forma bastante simples e intuitiva que permite que você importe apenas os pacotes Python que forem necessários, e integrá-los com as funções de sua API em algumas linhas de código, *literalmente*.
Você verá exemplos disso nos próximos capítulos, acerca de bancos de dados relacionais e NoSQL, segurança, etc.
## Compatibilidade do **FastAPI**
A simplicidade do sistema de injeção de dependência do **FastAPI** faz ele compatível com:
* todos os bancos de dados relacionais
* bancos de dados NoSQL
* pacotes externos
* APIs externas
* sistemas de autenticação e autorização
* istemas de monitoramento de uso para APIs
* sistemas de injeção de dados de resposta
* etc.
## Simples e Poderoso
Mesmo que o sistema hierárquico de injeção de dependência seja simples de definir e utilizar, ele ainda é bastante poderoso.
Você pode definir dependências que por sua vez definem suas próprias dependências.
No fim, uma árvore hierárquica de dependências é criadas, e o sistema de **Injeção de Dependência** toma conta de resolver todas essas dependências (e as sub-dependências delas) para você, e provê (injeta) os resultados em cada passo.
Por exemplo, vamos supor que você possua 4 endpoints na sua API (*operações de rota*):
* `/items/public/`
* `/items/private/`
* `/users/{user_id}/activate`
* `/items/pro/`
Você poderia adicionar diferentes requisitos de permissão para cada um deles utilizando apenas dependências e sub-dependências:
```mermaid
graph TB
current_user(["current_user"])
active_user(["active_user"])
admin_user(["admin_user"])
paying_user(["paying_user"])
public["/items/public/"]
private["/items/private/"]
activate_user["/users/{user_id}/activate"]
pro_items["/items/pro/"]
current_user --> active_user
active_user --> admin_user
active_user --> paying_user
current_user --> public
active_user --> private
admin_user --> activate_user
paying_user --> pro_items
```
## Integração com **OpenAPI**
Todas essas dependências, ao declarar os requisitos para suas *operações de rota*, também adicionam parâmetros, validações, etc.
O **FastAPI** se encarrega de adicionar tudo isso ao esquema OpenAPI, para que seja mostrado nos sistemas de documentação interativa.

134
docs/zh/docs/tutorial/security/oauth2-jwt.md

@ -26,29 +26,25 @@ JWT 字符串没有加密,任何人都能用它恢复原始信息。
如需深入了解 JWT 令牌,了解它的工作方式,请参阅 <a href="https://jwt.io/" class="external-link" target="_blank">https://jwt.io</a> 如需深入了解 JWT 令牌,了解它的工作方式,请参阅 <a href="https://jwt.io/" class="external-link" target="_blank">https://jwt.io</a>
## 安装 `python-jose` ## 安装 `PyJWT`
安装 `python-jose`,在 Python 中生成和校验 JWT 令牌: 安装 `PyJWT`,在 Python 中生成和校验 JWT 令牌:
<div class="termy"> <div class="termy">
```console ```console
$ pip install python-jose[cryptography] $ pip install pyjwt
---> 100% ---> 100%
``` ```
</div> </div>
<a href="https://github.com/mpdavis/python-jose" class="external-link" target="_blank">Python-jose</a> 需要安装配套的加密后端。 !!! info "说明"
本教程推荐的后端是:<a href="https://cryptography.io/" class="external-link" target="_blank">pyca/cryptography</a> 如果您打算使用类似 RSA 或 ECDSA 的数字签名算法,您应该安装加密库依赖项 `pyjwt[crypto]`
!!! tip "提示" 您可以在 <a href="https://pyjwt.readthedocs.io/en/latest/installation.html" class="external-link" target="_blank">PyJWT Installation docs</a> 获得更多信息。
本教程以前使用 <a href="https://pyjwt.readthedocs.io/" class="external-link" target="_blank">PyJWT</a>
但后来换成了 Python-jose,因为 Python-jose 支持 PyJWT 的所有功能,还支持与其它工具集成时可能会用到的一些其它功能。
## 密码哈希 ## 密码哈希
@ -62,7 +58,7 @@ $ pip install python-jose[cryptography]
原因很简单,假如数据库被盗,窃贼无法获取用户的明文密码,得到的只是哈希值。 原因很简单,假如数据库被盗,窃贼无法获取用户的明文密码,得到的只是哈希值。
这样一来,窃贼就无法在其它应用中使用窃取的密码要知道,很多用户在所有系统中都使用相同的密码,风险超大)。 这样一来,窃贼就无法在其它应用中使用窃取的密码要知道,很多用户在所有系统中都使用相同的密码,风险超大)。
## 安装 `passlib` ## 安装 `passlib`
@ -112,9 +108,41 @@ $ pip install passlib[bcrypt]
第三个函数用于身份验证,并返回用户。 第三个函数用于身份验证,并返回用户。
```Python hl_lines="7 48 55-56 59-60 69-75" === "Python 3.10+"
{!../../../docs_src/security/tutorial004.py!}
``` ```Python hl_lines="8 49 56-57 60-61 70-76"
{!> ../../../docs_src/security/tutorial004_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="8 49 56-57 60-61 70-76"
{!> ../../../docs_src/security/tutorial004_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="8 50 57-58 61-62 71-77"
{!> ../../../docs_src/security/tutorial004_an.py!}
```
=== "Python 3.10+ non-Annotated"
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="7 48 55-56 59-60 69-75"
{!> ../../../docs_src/security/tutorial004_py310.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="8 49 56-57 60-61 70-76"
{!> ../../../docs_src/security/tutorial004.py!}
```
!!! note "笔记" !!! note "笔记"
@ -160,9 +188,41 @@ $ openssl rand -hex 32
如果令牌无效,则直接返回 HTTP 错误。 如果令牌无效,则直接返回 HTTP 错误。
```Python hl_lines="89-106" === "Python 3.10+"
{!../../../docs_src/security/tutorial004.py!}
``` ```Python hl_lines="4 7 13-15 29-31 79-87"
{!> ../../../docs_src/security/tutorial004_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="4 7 13-15 29-31 79-87"
{!> ../../../docs_src/security/tutorial004_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="4 7 14-16 30-32 80-88"
{!> ../../../docs_src/security/tutorial004_an.py!}
```
=== "Python 3.10+ non-Annotated"
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="3 6 12-14 28-30 78-86"
{!> ../../../docs_src/security/tutorial004_py310.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="4 7 13-15 29-31 79-87"
{!> ../../../docs_src/security/tutorial004.py!}
```
## 更新 `/token` *路径操作* ## 更新 `/token` *路径操作*
@ -170,9 +230,41 @@ $ openssl rand -hex 32
创建并返回真正的 JWT 访问令牌。 创建并返回真正的 JWT 访问令牌。
```Python hl_lines="115-130" === "Python 3.10+"
{!../../../docs_src/security/tutorial004.py!}
``` ```Python hl_lines="118-133"
{!> ../../../docs_src/security/tutorial004_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="118-133"
{!> ../../../docs_src/security/tutorial004_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="119-134"
{!> ../../../docs_src/security/tutorial004_an.py!}
```
=== "Python 3.10+ non-Annotated"
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="115-130"
{!> ../../../docs_src/security/tutorial004_py310.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="116-131"
{!> ../../../docs_src/security/tutorial004.py!}
```
### JWT `sub` 的技术细节 ### JWT `sub` 的技术细节
@ -261,7 +353,7 @@ OAuth2 支持**`scopes`**(作用域)。
开发者可以灵活选择最适合项目的安全机制。 开发者可以灵活选择最适合项目的安全机制。
还可以直接使用 `passlib``python-jose` 等维护良好、使用广泛的包,这是因为 **FastAPI** 不需要任何复杂机制,就能集成外部的包。 还可以直接使用 `passlib``PyJWT` 等维护良好、使用广泛的包,这是因为 **FastAPI** 不需要任何复杂机制,就能集成外部的包。
而且,**FastAPI** 还提供了一些工具,在不影响灵活、稳定和安全的前提下,尽可能地简化安全机制。 而且,**FastAPI** 还提供了一些工具,在不影响灵活、稳定和安全的前提下,尽可能地简化安全机制。

Loading…
Cancel
Save