Merge branch 'master' into bugfix/responses-model-openapi

This commit is contained in:
Felix Fanghaenel 2024-06-03 10:53:12 +02:00 committed by GitHub
commit 1ab4f26852
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
54 changed files with 1134 additions and 652 deletions

View File

@ -55,6 +55,7 @@ The key features are:
<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://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://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://databento.com/" target="_blank" title="Pay as you go for market data"><img src="https://fastapi.tiangolo.com/img/sponsors/databento.svg"></a>

View File

@ -96,8 +96,8 @@ Sie können wahrscheinlich mit der rechten Maustaste auf jeden Link klicken und
**Swagger UI** verwendet folgende Dateien:
* <a href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5.9.0/swagger-ui-bundle.js" class="external-link" target="_blank">`swagger-ui-bundle.js`</a>
* <a href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5.9.0/swagger-ui.css" class="external-link" target="_blank">`swagger-ui.css`</a>
* <a href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js" class="external-link" target="_blank">`swagger-ui-bundle.js`</a>
* <a href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css" class="external-link" target="_blank">`swagger-ui.css`</a>
Und **ReDoc** verwendet diese Datei:

View File

@ -17,6 +17,9 @@ sponsors:
- login: cryptapi
avatarUrl: https://avatars.githubusercontent.com/u/44925437?u=61369138589bc7fee6c417f3fbd50fbd38286cc4&v=4
url: https://github.com/cryptapi
- login: Kong
avatarUrl: https://avatars.githubusercontent.com/u/962416?v=4
url: https://github.com/Kong
- login: codacy
avatarUrl: https://avatars.githubusercontent.com/u/1834093?v=4
url: https://github.com/codacy
@ -48,7 +51,7 @@ sponsors:
avatarUrl: https://avatars.githubusercontent.com/u/74335107?v=4
url: https://github.com/xoflare
- login: marvin-robot
avatarUrl: https://avatars.githubusercontent.com/u/41086007?u=091c5cb75af363123d66f58194805a97220ee1a7&v=4
avatarUrl: https://avatars.githubusercontent.com/u/41086007?u=b9fcab402d0cd0aec738b6574fe60855cb0cd36d&v=4
url: https://github.com/marvin-robot
- login: BoostryJP
avatarUrl: https://avatars.githubusercontent.com/u/57932412?v=4
@ -68,9 +71,6 @@ sponsors:
- login: mainframeindustries
avatarUrl: https://avatars.githubusercontent.com/u/55092103?v=4
url: https://github.com/mainframeindustries
- login: AccentDesign
avatarUrl: https://avatars.githubusercontent.com/u/2429332?v=4
url: https://github.com/AccentDesign
- login: mangualero
avatarUrl: https://avatars.githubusercontent.com/u/3422968?u=c59272d7b5a912d6126fd6c6f17db71e20f506eb&v=4
url: https://github.com/mangualero
@ -86,7 +86,10 @@ sponsors:
- login: povilasb
avatarUrl: https://avatars.githubusercontent.com/u/1213442?u=b11f58ed6ceea6e8297c9b310030478ebdac894d&v=4
url: https://github.com/povilasb
- - login: upciti
- - login: jhundman
avatarUrl: https://avatars.githubusercontent.com/u/24263908?v=4
url: https://github.com/jhundman
- login: upciti
avatarUrl: https://avatars.githubusercontent.com/u/43346262?v=4
url: https://github.com/upciti
- - login: samuelcolvin
@ -116,9 +119,6 @@ sponsors:
- login: ProteinQure
avatarUrl: https://avatars.githubusercontent.com/u/33707203?v=4
url: https://github.com/ProteinQure
- login: wdwinslow
avatarUrl: https://avatars.githubusercontent.com/u/11562137?u=dc01daafb354135603a263729e3d26d939c0c452&v=4
url: https://github.com/wdwinslow
- login: catherinenelson1
avatarUrl: https://avatars.githubusercontent.com/u/11951946?u=e714b957185b8cf3d301cced7fc3ad2842122c6a&v=4
url: https://github.com/catherinenelson1
@ -149,12 +149,6 @@ sponsors:
- login: RaamEEIL
avatarUrl: https://avatars.githubusercontent.com/u/20320552?v=4
url: https://github.com/RaamEEIL
- login: CodeProcessor
avatarUrl: https://avatars.githubusercontent.com/u/24785073?u=b4dd0ef3f42ced86412a060dd2bd6c8caaf771aa&v=4
url: https://github.com/CodeProcessor
- login: patsatsia
avatarUrl: https://avatars.githubusercontent.com/u/61111267?u=3271b85f7a37b479c8d0ae0a235182e83c166edf&v=4
url: https://github.com/patsatsia
- login: anthonycepeda
avatarUrl: https://avatars.githubusercontent.com/u/72019805?u=60bdf46240cff8fca482ff0fc07d963fd5e1a27c&v=4
url: https://github.com/anthonycepeda
@ -167,6 +161,9 @@ sponsors:
- login: DelfinaCare
avatarUrl: https://avatars.githubusercontent.com/u/83734439?v=4
url: https://github.com/DelfinaCare
- login: Eruditis
avatarUrl: https://avatars.githubusercontent.com/u/95244703?v=4
url: https://github.com/Eruditis
- login: jugeeem
avatarUrl: https://avatars.githubusercontent.com/u/116043716?u=ae590d79c38ac79c91b9c5caa6887d061e865a3d&v=4
url: https://github.com/jugeeem
@ -188,9 +185,9 @@ sponsors:
- login: prodhype
avatarUrl: https://avatars.githubusercontent.com/u/60444672?u=3f278cff25ea37ead487d7861d4a984795de819e&v=4
url: https://github.com/prodhype
- login: koconder
avatarUrl: https://avatars.githubusercontent.com/u/25068?u=582657b23622aaa3dfe68bd028a780f272f456fa&v=4
url: https://github.com/koconder
- login: patsatsia
avatarUrl: https://avatars.githubusercontent.com/u/61111267?u=3271b85f7a37b479c8d0ae0a235182e83c166edf&v=4
url: https://github.com/patsatsia
- login: tcsmith
avatarUrl: https://avatars.githubusercontent.com/u/989034?u=7d8d741552b3279e8f4d3878679823a705a46f8f&v=4
url: https://github.com/tcsmith
@ -209,6 +206,21 @@ sponsors:
- login: Shark009
avatarUrl: https://avatars.githubusercontent.com/u/3163309?u=0c6f4091b0eda05c44c390466199826e6dc6e431&v=4
url: https://github.com/Shark009
- login: dblackrun
avatarUrl: https://avatars.githubusercontent.com/u/3528486?v=4
url: https://github.com/dblackrun
- login: zsinx6
avatarUrl: https://avatars.githubusercontent.com/u/3532625?u=ba75a5dc744d1116ccfeaaf30d41cb2fe81fe8dd&v=4
url: https://github.com/zsinx6
- login: kennywakeland
avatarUrl: https://avatars.githubusercontent.com/u/3631417?u=7c8f743f1ae325dfadea7c62bbf1abd6a824fc55&v=4
url: https://github.com/kennywakeland
- login: simw
avatarUrl: https://avatars.githubusercontent.com/u/6322526?v=4
url: https://github.com/simw
- login: koconder
avatarUrl: https://avatars.githubusercontent.com/u/25068?u=582657b23622aaa3dfe68bd028a780f272f456fa&v=4
url: https://github.com/koconder
- login: jstanden
avatarUrl: https://avatars.githubusercontent.com/u/63288?u=c3658d57d2862c607a0e19c2101c3c51876e36ad&v=4
url: https://github.com/jstanden
@ -224,9 +236,6 @@ sponsors:
- login: ericof
avatarUrl: https://avatars.githubusercontent.com/u/306014?u=cf7c8733620397e6584a451505581c01c5d842d7&v=4
url: https://github.com/ericof
- login: falquaddoomi
avatarUrl: https://avatars.githubusercontent.com/u/312923?u=aab6efa665ed9495ce37371af1cd637ec554772f&v=4
url: https://github.com/falquaddoomi
- login: wshayes
avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
url: https://github.com/wshayes
@ -239,12 +248,6 @@ sponsors:
- login: mintuhouse
avatarUrl: https://avatars.githubusercontent.com/u/769950?u=ecfbd79a97d33177e0d093ddb088283cf7fe8444&v=4
url: https://github.com/mintuhouse
- login: dblackrun
avatarUrl: https://avatars.githubusercontent.com/u/3528486?v=4
url: https://github.com/dblackrun
- login: simw
avatarUrl: https://avatars.githubusercontent.com/u/6322526?v=4
url: https://github.com/simw
- login: Rehket
avatarUrl: https://avatars.githubusercontent.com/u/7015688?u=3afb0ba200feebbc7f958950e92db34df2a3c172&v=4
url: https://github.com/Rehket
@ -254,12 +257,9 @@ sponsors:
- login: TrevorBenson
avatarUrl: https://avatars.githubusercontent.com/u/9167887?u=afdd1766fdb79e04e59094cc6a54cd011ee7f686&v=4
url: https://github.com/TrevorBenson
- login: zsinx6
avatarUrl: https://avatars.githubusercontent.com/u/3532625?u=ba75a5dc744d1116ccfeaaf30d41cb2fe81fe8dd&v=4
url: https://github.com/zsinx6
- login: kennywakeland
avatarUrl: https://avatars.githubusercontent.com/u/3631417?u=7c8f743f1ae325dfadea7c62bbf1abd6a824fc55&v=4
url: https://github.com/kennywakeland
- login: wdwinslow
avatarUrl: https://avatars.githubusercontent.com/u/11562137?u=dc01daafb354135603a263729e3d26d939c0c452&v=4
url: https://github.com/wdwinslow
- login: aacayaco
avatarUrl: https://avatars.githubusercontent.com/u/3634801?u=eaadda178c964178fcb64886f6c732172c8f8219&v=4
url: https://github.com/aacayaco
@ -269,6 +269,9 @@ sponsors:
- login: jgreys
avatarUrl: https://avatars.githubusercontent.com/u/4136890?u=096820d1ef89877d57d0f68e669ead8b0fde84df&v=4
url: https://github.com/jgreys
- 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
@ -308,9 +311,6 @@ sponsors:
- login: rlnchow
avatarUrl: https://avatars.githubusercontent.com/u/28018479?u=a93ca9cf1422b9ece155784a72d5f2fdbce7adff&v=4
url: https://github.com/rlnchow
- login: dvlpjrs
avatarUrl: https://avatars.githubusercontent.com/u/32254642?u=fbd6ad0324d4f1eb6231cf775be1c7bd4404e961&v=4
url: https://github.com/dvlpjrs
- login: engineerjoe440
avatarUrl: https://avatars.githubusercontent.com/u/33275230?u=eb223cad27017bb1e936ee9b429b450d092d0236&v=4
url: https://github.com/engineerjoe440
@ -320,9 +320,9 @@ sponsors:
- login: DevOpsKev
avatarUrl: https://avatars.githubusercontent.com/u/36336550?u=6ccd5978fdaab06f37e22f2a14a7439341df7f67&v=4
url: https://github.com/DevOpsKev
- login: Zuzah
avatarUrl: https://avatars.githubusercontent.com/u/10934846?u=1ef43e075ddc87bd1178372bf4d95ee6175cae27&v=4
url: https://github.com/Zuzah
- login: petercool
avatarUrl: https://avatars.githubusercontent.com/u/37613029?u=81c525232bb35780945a68e88afd96bb2cdad9c4&v=4
url: https://github.com/petercool
- login: JimFawkes
avatarUrl: https://avatars.githubusercontent.com/u/12075115?u=dc58ecfd064d72887c34bf500ddfd52592509acd&v=4
url: https://github.com/JimFawkes
@ -338,18 +338,24 @@ sponsors:
- login: jangia
avatarUrl: https://avatars.githubusercontent.com/u/17927101?u=9261b9bb0c3e3bb1ecba43e8915dc58d8c9a077e&v=4
url: https://github.com/jangia
- login: jackleeio
avatarUrl: https://avatars.githubusercontent.com/u/20477587?u=c5184dab6d021733d10c8f975b20e391856303d6&v=4
url: https://github.com/jackleeio
- login: shuheng-liu
avatarUrl: https://avatars.githubusercontent.com/u/22414322?u=813c45f30786c6b511b21a661def025d8f7b609e&v=4
url: https://github.com/shuheng-liu
- login: pers0n4
avatarUrl: https://avatars.githubusercontent.com/u/24864600?u=f211a13a7b572cbbd7779b9c8d8cb428cc7ba07e&v=4
url: https://github.com/pers0n4
- login: curegit
avatarUrl: https://avatars.githubusercontent.com/u/37978051?u=1733c322079118c0cdc573c03d92813f50a9faec&v=4
url: https://github.com/curegit
- login: fernandosmither
avatarUrl: https://avatars.githubusercontent.com/u/66154723?u=a76a037b5d674938a75d2cff862fb6dfd63ec214&v=4
avatarUrl: https://avatars.githubusercontent.com/u/66154723?u=f79753eb207d01cca5bbb91ac62db6123e7622d1&v=4
url: https://github.com/fernandosmither
- login: romabozhanovgithub
avatarUrl: https://avatars.githubusercontent.com/u/67696229?u=e4b921eef096415300425aca249348f8abb78ad7&v=4
url: https://github.com/romabozhanovgithub
- login: PunRabbit
avatarUrl: https://avatars.githubusercontent.com/u/70463212?u=1a835cfbc99295a60c8282f6aa6199d1b42241a5&v=4
url: https://github.com/PunRabbit
- login: PelicanQ
avatarUrl: https://avatars.githubusercontent.com/u/77930606?v=4
url: https://github.com/PelicanQ
@ -359,12 +365,6 @@ sponsors:
- login: zk-Call
avatarUrl: https://avatars.githubusercontent.com/u/147117264?v=4
url: https://github.com/zk-Call
- login: petercool
avatarUrl: https://avatars.githubusercontent.com/u/37613029?u=81c525232bb35780945a68e88afd96bb2cdad9c4&v=4
url: https://github.com/petercool
- login: curegit
avatarUrl: https://avatars.githubusercontent.com/u/37978051?u=1733c322079118c0cdc573c03d92813f50a9faec&v=4
url: https://github.com/curegit
- login: kristiangronberg
avatarUrl: https://avatars.githubusercontent.com/u/42678548?v=4
url: https://github.com/kristiangronberg
@ -380,15 +380,18 @@ sponsors:
- login: ArtyomVancyan
avatarUrl: https://avatars.githubusercontent.com/u/44609997?v=4
url: https://github.com/ArtyomVancyan
- login: harol97
avatarUrl: https://avatars.githubusercontent.com/u/49042862?u=2b18e115ab73f5f09a280be2850f93c58a12e3d2&v=4
url: https://github.com/harol97
- login: hgalytoby
avatarUrl: https://avatars.githubusercontent.com/u/50397689?u=62c7ff3519858423579676cd0efbd7e3f1ffe63a&v=4
url: https://github.com/hgalytoby
- login: conservative-dude
avatarUrl: https://avatars.githubusercontent.com/u/55538308?u=f250c44942ea6e73a6bd90739b381c470c192c11&v=4
url: https://github.com/conservative-dude
- login: tochikuji
avatarUrl: https://avatars.githubusercontent.com/u/851759?v=4
url: https://github.com/tochikuji
- login: Joaopcamposs
avatarUrl: https://avatars.githubusercontent.com/u/57376574?u=699d5ba5ee66af1d089df6b5e532b97169e73650&v=4
url: https://github.com/Joaopcamposs
- login: browniebroke
avatarUrl: https://avatars.githubusercontent.com/u/861044?u=5abfca5588f3e906b31583d7ee62f6de4b68aa24&v=4
url: https://github.com/browniebroke
@ -407,9 +410,6 @@ sponsors:
- login: cbonoz
avatarUrl: https://avatars.githubusercontent.com/u/2351087?u=fd3e8030b2cc9fbfbb54a65e9890c548a016f58b&v=4
url: https://github.com/cbonoz
- login: anthonycorletti
avatarUrl: https://avatars.githubusercontent.com/u/3477132?u=dfe51d2080fbd3fee81e05911cd8d50da9dcc709&v=4
url: https://github.com/anthonycorletti
- login: ddanier
avatarUrl: https://avatars.githubusercontent.com/u/113563?u=ed1dc79de72f93bd78581f88ebc6952b62f472da&v=4
url: https://github.com/ddanier
@ -431,6 +431,9 @@ sponsors:
- login: securancy
avatarUrl: https://avatars.githubusercontent.com/u/606673?v=4
url: https://github.com/securancy
- login: tochikuji
avatarUrl: https://avatars.githubusercontent.com/u/851759?v=4
url: https://github.com/tochikuji
- login: KentShikama
avatarUrl: https://avatars.githubusercontent.com/u/6329898?u=8b236810db9b96333230430837e1f021f9246da1&v=4
url: https://github.com/KentShikama
@ -450,7 +453,7 @@ sponsors:
avatarUrl: https://avatars.githubusercontent.com/u/9369632?u=8c988f1b008a3f601385a3616f9327820f66e3a5&v=4
url: https://github.com/msehnout
- login: xncbf
avatarUrl: https://avatars.githubusercontent.com/u/9462045?u=ee91e210ae93b9cdd8f248b21cb028316cc0b747&v=4
avatarUrl: https://avatars.githubusercontent.com/u/9462045?u=2ef1ede118a72c170805f50b9ad07341fd16a354&v=4
url: https://github.com/xncbf
- login: DMantis
avatarUrl: https://avatars.githubusercontent.com/u/9536869?v=4
@ -473,6 +476,9 @@ sponsors:
- 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: Alisa-lisa
avatarUrl: https://avatars.githubusercontent.com/u/4137964?u=e7e393504f554f4ff15863a1e01a5746863ef9ce&v=4
url: https://github.com/Alisa-lisa
@ -503,24 +509,24 @@ sponsors:
- - login: danburonline
avatarUrl: https://avatars.githubusercontent.com/u/34251194?u=94935cccfbec58083ab1e535212d54f1bf2c978a&v=4
url: https://github.com/danburonline
- login: AliYmn
avatarUrl: https://avatars.githubusercontent.com/u/18416653?u=0de5a262e8b4dc0a08d065f30f7a39941e246530&v=4
url: https://github.com/AliYmn
- login: sadikkuzu
avatarUrl: https://avatars.githubusercontent.com/u/23168063?u=d179c06bb9f65c4167fcab118526819f8e0dac17&v=4
url: https://github.com/sadikkuzu
- login: Mehver
avatarUrl: https://avatars.githubusercontent.com/u/75297777?u=dcd857f4278df055d98cd3486c2ce8bad368eb50&v=4
url: https://github.com/Mehver
- login: tran-hai-long
avatarUrl: https://avatars.githubusercontent.com/u/119793901?u=3b173a845dcf099b275bdc9713a69cbbc36040ce&v=4
url: https://github.com/tran-hai-long
- login: rwxd
avatarUrl: https://avatars.githubusercontent.com/u/40308458?u=cd04a39e3655923be4f25c2ba8a5a07b3da3230a&v=4
url: https://github.com/rwxd
- login: zee229
avatarUrl: https://avatars.githubusercontent.com/u/48365508?u=eac8e8bb968ed3391439a98490d3e6e5f6f2826b&v=4
url: https://github.com/zee229
- login: Patechoc
avatarUrl: https://avatars.githubusercontent.com/u/2376641?u=23b49e9eda04f078cb74fa3f93593aa6a57bb138&v=4
url: https://github.com/Patechoc
- login: ssbarnea
avatarUrl: https://avatars.githubusercontent.com/u/102495?u=c2efbf6fea2737e21dfc6b1113c4edc9644e9eaa&v=4
url: https://github.com/ssbarnea
- login: yuawn
avatarUrl: https://avatars.githubusercontent.com/u/5111198?u=5315576f3fe1a70fd2d0f02181588f4eea5d353d&v=4
url: https://github.com/yuawn
- login: dongzhenye
avatarUrl: https://avatars.githubusercontent.com/u/5765843?u=fe420c9a4c41e5b060faaf44029f5485616b470d&v=4
url: https://github.com/dongzhenye

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,9 @@ gold:
- 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
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
title: Kong Konnect - API management platform
img: https://fastapi.tiangolo.com/img/sponsors/kong.png
silver:
- url: https://training.talkpython.fm/fastapi-courses
title: FastAPI video courses on demand from people you trust

View File

@ -224,7 +224,7 @@ Here, `new_dict` will contain all the key-value pairs from `old_dict` plus the n
}
```
You can use that technique to re-use some predefined responses in your *path operations* and combine them with additional custom ones.
You can use that technique to reuse some predefined responses in your *path operations* and combine them with additional custom ones.
For example:

View File

@ -187,6 +187,6 @@ And then in our code, we parse that YAML content directly, and then we are again
In Pydantic version 1 the method to parse and validate an object was `Item.parse_obj()`, in Pydantic version 2, the method is called `Item.model_validate()`.
!!! tip
Here we re-use the same Pydantic model.
Here we reuse the same Pydantic model.
But the same way, we could have validated it in some other way.

View File

@ -58,19 +58,19 @@ First, let's quickly see the parts that change from the examples in the main **T
=== "Python 3.10+"
```Python hl_lines="4 8 12 46 64 105 107-115 121-124 128-134 139 155"
```Python hl_lines="5 9 13 47 65 106 108-116 122-125 129-135 140 156"
{!> ../../../docs_src/security/tutorial005_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="2 4 8 12 46 64 105 107-115 121-124 128-134 139 155"
```Python hl_lines="2 5 9 13 47 65 106 108-116 122-125 129-135 140 156"
{!> ../../../docs_src/security/tutorial005_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="2 4 8 12 47 65 106 108-116 122-125 129-135 140 156"
```Python hl_lines="2 5 9 13 48 66 107 109-117 123-126 130-136 141 157"
{!> ../../../docs_src/security/tutorial005_an.py!}
```
@ -79,7 +79,7 @@ First, let's quickly see the parts that change from the examples in the main **T
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="3 7 11 45 63 104 106-114 120-123 127-133 138 154"
```Python hl_lines="4 8 12 46 64 105 107-115 121-124 128-134 139 155"
{!> ../../../docs_src/security/tutorial005_py310.py!}
```
@ -88,7 +88,7 @@ First, let's quickly see the parts that change from the examples in the main **T
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="2 4 8 12 46 64 105 107-115 121-124 128-134 139 155"
```Python hl_lines="2 5 9 13 47 65 106 108-116 122-125 129-135 140 156"
{!> ../../../docs_src/security/tutorial005_py39.py!}
```
@ -97,7 +97,7 @@ First, let's quickly see the parts that change from the examples in the main **T
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="2 4 8 12 46 64 105 107-115 121-124 128-134 139 155"
```Python hl_lines="2 5 9 13 47 65 106 108-116 122-125 129-135 140 156"
{!> ../../../docs_src/security/tutorial005.py!}
```
@ -111,19 +111,19 @@ The `scopes` parameter receives a `dict` with each scope as a key and the descri
=== "Python 3.10+"
```Python hl_lines="62-65"
```Python hl_lines="63-66"
{!> ../../../docs_src/security/tutorial005_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="62-65"
```Python hl_lines="63-66"
{!> ../../../docs_src/security/tutorial005_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="63-66"
```Python hl_lines="64-67"
{!> ../../../docs_src/security/tutorial005_an.py!}
```
@ -132,7 +132,7 @@ The `scopes` parameter receives a `dict` with each scope as a key and the descri
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="61-64"
```Python hl_lines="62-65"
{!> ../../../docs_src/security/tutorial005_py310.py!}
```
@ -142,7 +142,7 @@ The `scopes` parameter receives a `dict` with each scope as a key and the descri
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="62-65"
```Python hl_lines="63-66"
{!> ../../../docs_src/security/tutorial005_py39.py!}
```
@ -151,7 +151,7 @@ The `scopes` parameter receives a `dict` with each scope as a key and the descri
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="62-65"
```Python hl_lines="63-66"
{!> ../../../docs_src/security/tutorial005.py!}
```
@ -178,19 +178,19 @@ And we return the scopes as part of the JWT token.
=== "Python 3.10+"
```Python hl_lines="155"
```Python hl_lines="156"
{!> ../../../docs_src/security/tutorial005_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="155"
```Python hl_lines="156"
{!> ../../../docs_src/security/tutorial005_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="156"
```Python hl_lines="157"
{!> ../../../docs_src/security/tutorial005_an.py!}
```
@ -199,7 +199,7 @@ And we return the scopes as part of the JWT token.
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="154"
```Python hl_lines="155"
{!> ../../../docs_src/security/tutorial005_py310.py!}
```
@ -208,7 +208,7 @@ And we return the scopes as part of the JWT token.
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="155"
```Python hl_lines="156"
{!> ../../../docs_src/security/tutorial005_py39.py!}
```
@ -217,7 +217,7 @@ And we return the scopes as part of the JWT token.
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="155"
```Python hl_lines="156"
{!> ../../../docs_src/security/tutorial005.py!}
```
@ -244,19 +244,19 @@ In this case, it requires the scope `me` (it could require more than one scope).
=== "Python 3.10+"
```Python hl_lines="4 139 170"
```Python hl_lines="5 140 171"
{!> ../../../docs_src/security/tutorial005_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="4 139 170"
```Python hl_lines="5 140 171"
{!> ../../../docs_src/security/tutorial005_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="4 140 171"
```Python hl_lines="5 141 172"
{!> ../../../docs_src/security/tutorial005_an.py!}
```
@ -265,7 +265,7 @@ In this case, it requires the scope `me` (it could require more than one scope).
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="3 138 167"
```Python hl_lines="4 139 168"
{!> ../../../docs_src/security/tutorial005_py310.py!}
```
@ -274,7 +274,7 @@ In this case, it requires the scope `me` (it could require more than one scope).
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="4 139 168"
```Python hl_lines="5 140 169"
{!> ../../../docs_src/security/tutorial005_py39.py!}
```
@ -283,7 +283,7 @@ In this case, it requires the scope `me` (it could require more than one scope).
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="4 139 168"
```Python hl_lines="5 140 169"
{!> ../../../docs_src/security/tutorial005.py!}
```
@ -310,19 +310,19 @@ This `SecurityScopes` class is similar to `Request` (`Request` was used to get t
=== "Python 3.10+"
```Python hl_lines="8 105"
```Python hl_lines="9 106"
{!> ../../../docs_src/security/tutorial005_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="8 105"
```Python hl_lines="9 106"
{!> ../../../docs_src/security/tutorial005_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="8 106"
```Python hl_lines="9 107"
{!> ../../../docs_src/security/tutorial005_an.py!}
```
@ -331,7 +331,7 @@ This `SecurityScopes` class is similar to `Request` (`Request` was used to get t
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="7 104"
```Python hl_lines="8 105"
{!> ../../../docs_src/security/tutorial005_py310.py!}
```
@ -340,7 +340,7 @@ This `SecurityScopes` class is similar to `Request` (`Request` was used to get t
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="8 105"
```Python hl_lines="9 106"
{!> ../../../docs_src/security/tutorial005_py39.py!}
```
@ -349,7 +349,7 @@ This `SecurityScopes` class is similar to `Request` (`Request` was used to get t
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="8 105"
```Python hl_lines="9 106"
{!> ../../../docs_src/security/tutorial005.py!}
```
@ -361,25 +361,25 @@ It will have a property `scopes` with a list containing all the scopes required
The `security_scopes` object (of class `SecurityScopes`) also provides a `scope_str` attribute with a single string, containing those scopes separated by spaces (we are going to use it).
We create an `HTTPException` that we can re-use (`raise`) later at several points.
We create an `HTTPException` that we can reuse (`raise`) later at several points.
In this exception, we include the scopes required (if any) as a string separated by spaces (using `scope_str`). We put that string containing the scopes in the `WWW-Authenticate` header (this is part of the spec).
=== "Python 3.10+"
```Python hl_lines="105 107-115"
```Python hl_lines="106 108-116"
{!> ../../../docs_src/security/tutorial005_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="105 107-115"
```Python hl_lines="106 108-116"
{!> ../../../docs_src/security/tutorial005_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="106 108-116"
```Python hl_lines="107 109-117"
{!> ../../../docs_src/security/tutorial005_an.py!}
```
@ -388,7 +388,7 @@ In this exception, we include the scopes required (if any) as a string separated
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="104 106-114"
```Python hl_lines="105 107-115"
{!> ../../../docs_src/security/tutorial005_py310.py!}
```
@ -397,7 +397,7 @@ In this exception, we include the scopes required (if any) as a string separated
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="105 107-115"
```Python hl_lines="106 108-116"
{!> ../../../docs_src/security/tutorial005_py39.py!}
```
@ -406,7 +406,7 @@ In this exception, we include the scopes required (if any) as a string separated
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="105 107-115"
```Python hl_lines="106 108-116"
{!> ../../../docs_src/security/tutorial005.py!}
```
@ -426,19 +426,19 @@ We also verify that we have a user with that username, and if not, we raise that
=== "Python 3.10+"
```Python hl_lines="46 116-127"
```Python hl_lines="47 117-128"
{!> ../../../docs_src/security/tutorial005_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="46 116-127"
```Python hl_lines="47 117-128"
{!> ../../../docs_src/security/tutorial005_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="47 117-128"
```Python hl_lines="48 118-129"
{!> ../../../docs_src/security/tutorial005_an.py!}
```
@ -447,7 +447,7 @@ We also verify that we have a user with that username, and if not, we raise that
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="45 115-126"
```Python hl_lines="46 116-127"
{!> ../../../docs_src/security/tutorial005_py310.py!}
```
@ -456,7 +456,7 @@ We also verify that we have a user with that username, and if not, we raise that
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="46 116-127"
```Python hl_lines="47 117-128"
{!> ../../../docs_src/security/tutorial005_py39.py!}
```
@ -465,7 +465,7 @@ We also verify that we have a user with that username, and if not, we raise that
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="46 116-127"
```Python hl_lines="47 117-128"
{!> ../../../docs_src/security/tutorial005.py!}
```
@ -477,19 +477,19 @@ For this, we use `security_scopes.scopes`, that contains a `list` with all these
=== "Python 3.10+"
```Python hl_lines="128-134"
```Python hl_lines="129-135"
{!> ../../../docs_src/security/tutorial005_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="128-134"
```Python hl_lines="129-135"
{!> ../../../docs_src/security/tutorial005_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="129-135"
```Python hl_lines="130-136"
{!> ../../../docs_src/security/tutorial005_an.py!}
```
@ -498,7 +498,7 @@ For this, we use `security_scopes.scopes`, that contains a `list` with all these
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="127-133"
```Python hl_lines="128-134"
{!> ../../../docs_src/security/tutorial005_py310.py!}
```
@ -507,7 +507,7 @@ For this, we use `security_scopes.scopes`, that contains a `list` with all these
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="128-134"
```Python hl_lines="129-135"
{!> ../../../docs_src/security/tutorial005_py39.py!}
```
@ -516,7 +516,7 @@ For this, we use `security_scopes.scopes`, that contains a `list` with all these
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="128-134"
```Python hl_lines="129-135"
{!> ../../../docs_src/security/tutorial005.py!}
```

View File

@ -369,7 +369,7 @@ Here we define the config `env_file` inside of your Pydantic `Settings` class, a
### Creating the `Settings` only once with `lru_cache`
Reading a file from disk is normally a costly (slow) operation, so you probably want to do it only once and then re-use the same settings object, instead of reading it for each request.
Reading a file from disk is normally a costly (slow) operation, so you probably want to do it only once and then reuse the same settings object, instead of reading it for each request.
But every time we do:

View File

@ -23,7 +23,7 @@ $ pip install jinja2
## Using `Jinja2Templates`
* Import `Jinja2Templates`.
* Create a `templates` object that you can re-use later.
* Create a `templates` object that you can reuse later.
* Declare a `Request` parameter in the *path operation* that will return a template.
* Use the `templates` you created to render and return a `TemplateResponse`, pass the name of the template, the request object, and a "context" dictionary with key-value pairs to be used inside of the Jinja2 template.

View File

@ -222,7 +222,7 @@ All of the cashiers doing all the work with one client after the other 👨‍
And you have to wait 🕙 in the line for a long time or you lose your turn.
You probably wouldn't want to take your crush 😍 with you to do errands at the bank 🏦.
You probably wouldn't want to take your crush 😍 with you to run errands at the bank 🏦.
### Burger Conclusion

View File

@ -70,7 +70,7 @@ And there are many other images for different things like databases, for example
By using a pre-made container image it's very easy to **combine** and use different tools. For example, to try out a new database. In most cases, you can use the **official images**, and just configure them with environment variables.
That way, in many cases you can learn about containers and Docker and re-use that knowledge with many different tools and components.
That way, in many cases you can learn about containers and Docker and reuse that knowledge with many different tools and components.
So, you would run **multiple containers** with different things, like a database, a Python application, a web server with a React frontend application, and connect them together via their internal network.
@ -249,7 +249,7 @@ COPY ./requirements.txt /code/requirements.txt
Docker and other tools **build** these container images **incrementally**, adding **one layer on top of the other**, starting from the top of the `Dockerfile` and adding any files created by each of the instructions of the `Dockerfile`.
Docker and similar tools also use an **internal cache** when building the image, if a file hasn't changed since the last time building the container image, then it will **re-use the same layer** created the last time, instead of copying the file again and creating a new layer from scratch.
Docker and similar tools also use an **internal cache** when building the image, if a file hasn't changed since the last time building the container image, then it will **reuse the same layer** created the last time, instead of copying the file again and creating a new layer from scratch.
Just avoiding the copy of files doesn't necessarily improve things too much, but because it used the cache for that step, it can **use the cache for the next step**. For example, it could use the cache for the instruction that installs dependencies with:

View File

@ -26,7 +26,7 @@ To disable them, set their URLs to `None` when creating your `FastAPI` app:
Now you can create the *path operations* for the custom docs.
You can re-use FastAPI's internal functions to create the HTML pages for the docs, and pass them the needed arguments:
You can reuse FastAPI's internal functions to create the HTML pages for the docs, and pass them the needed arguments:
* `openapi_url`: the URL where the HTML page for the docs can get the OpenAPI schema for your API. You can use here the attribute `app.openapi_url`.
* `title`: the title of your API.
@ -96,8 +96,8 @@ You can probably right-click each link and select an option similar to `Save lin
**Swagger UI** uses the files:
* <a href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5.9.0/swagger-ui-bundle.js" class="external-link" target="_blank">`swagger-ui-bundle.js`</a>
* <a href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5.9.0/swagger-ui.css" class="external-link" target="_blank">`swagger-ui.css`</a>
* <a href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js" class="external-link" target="_blank">`swagger-ui-bundle.js`</a>
* <a href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css" class="external-link" target="_blank">`swagger-ui.css`</a>
And **ReDoc** uses the file:
@ -163,7 +163,7 @@ To disable them, set their URLs to `None` when creating your `FastAPI` app:
And the same way as with a custom CDN, now you can create the *path operations* for the custom docs.
Again, you can re-use FastAPI's internal functions to create the HTML pages for the docs, and pass them the needed arguments:
Again, you can reuse FastAPI's internal functions to create the HTML pages for the docs, and pass them the needed arguments:
* `openapi_url`: the URL where the HTML page for the docs can get the OpenAPI schema for your API. You can use here the attribute `app.openapi_url`.
* `title`: the title of your API.

View File

@ -108,7 +108,7 @@ Now create a function that will:
* Get the document with that ID.
* Put the contents of the document in a `UserInDB` model.
By creating a function that is only dedicated to getting your user from a `username` (or any other parameter) independent of your *path operation function*, you can more easily re-use it in multiple parts and also add <abbr title="Automated test, written in code, that checks if another piece of code is working correctly.">unit tests</abbr> for it:
By creating a function that is only dedicated to getting your user from a `username` (or any other parameter) independent of your *path operation function*, you can more easily reuse it in multiple parts and also add <abbr title="Automated test, written in code, that checks if another piece of code is working correctly.">unit tests</abbr> for it:
```Python hl_lines="36-42"
{!../../../docs_src/nosql_databases/tutorial001.py!}

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -476,7 +476,7 @@ You will see a lot more of all this in practice in the [Tutorial - User Guide](t
## Type Hints with Metadata Annotations
Python also has a feature that allows putting **additional metadata** in these type hints using `Annotated`.
Python also has a feature that allows putting **additional <abbr title="Data about the data, in this case, information about the type, e.g. a description.">metadata</abbr>** in these type hints using `Annotated`.
=== "Python 3.9+"

View File

@ -9,12 +9,34 @@ hide:
* 🌐 Add Turkish translation for `docs/tr/docs/tutorial/request-forms.md`. PR [#11553](https://github.com/tiangolo/fastapi/pull/11553) by [@hasansezertasan](https://github.com/hasansezertasan).
### Upgrades
* 📝 Restored Swagger-UI links to use the latest version possible.. PR [#11459](https://github.com/tiangolo/fastapi/pull/11459) by [@UltimateLobster](https://github.com/UltimateLobster).
### Docs
* 📝 Update `security/first-steps.md`. PR [#11674](https://github.com/tiangolo/fastapi/pull/11674) by [@alejsdev](https://github.com/alejsdev).
* 📝 Update `security/first-steps.md`. PR [#11673](https://github.com/tiangolo/fastapi/pull/11673) by [@alejsdev](https://github.com/alejsdev).
* 📝 Update note in `path-params-numeric-validations.md`. PR [#11672](https://github.com/tiangolo/fastapi/pull/11672) by [@alejsdev](https://github.com/alejsdev).
* 📝 Tweak intro docs about `Annotated` and `Query()` params. PR [#11664](https://github.com/tiangolo/fastapi/pull/11664) by [@tiangolo](https://github.com/tiangolo).
* 📝 Update JWT auth documentation to use PyJWT instead of pyhon-jose. PR [#11589](https://github.com/tiangolo/fastapi/pull/11589) by [@estebanx64](https://github.com/estebanx64).
* 📝 Update docs. PR [#11603](https://github.com/tiangolo/fastapi/pull/11603) by [@alejsdev](https://github.com/alejsdev).
* ✏️ Fix typo: convert every 're-use' to 'reuse'.. PR [#11598](https://github.com/tiangolo/fastapi/pull/11598) by [@hasansezertasan](https://github.com/hasansezertasan).
* ✏️ Fix typo in `fastapi/applications.py`. PR [#11593](https://github.com/tiangolo/fastapi/pull/11593) by [@petarmaric](https://github.com/petarmaric).
* ✏️ Fix link in `fastapi-cli.md`. PR [#11524](https://github.com/tiangolo/fastapi/pull/11524) by [@svlandeg](https://github.com/svlandeg).
### Translations
* 🌐 Add Turkish translation for `docs/tr/docs/deployment/cloud.md`. PR [#11610](https://github.com/tiangolo/fastapi/pull/11610) by [@hasansezertasan](https://github.com/hasansezertasan).
* 🌐 Add Turkish translation for `docs/tr/docs/advanced/security/index.md`. PR [#11609](https://github.com/tiangolo/fastapi/pull/11609) by [@hasansezertasan](https://github.com/hasansezertasan).
* 🌐 Add Turkish translation for `docs/tr/docs/advanced/testing-websockets.md`. PR [#11608](https://github.com/tiangolo/fastapi/pull/11608) by [@hasansezertasan](https://github.com/hasansezertasan).
* 🌐 Add Turkish translation for `docs/tr/docs/how-to/general.md`. PR [#11607](https://github.com/tiangolo/fastapi/pull/11607) by [@hasansezertasan](https://github.com/hasansezertasan).
* 🌐 Update Chinese translation for `docs/zh/docs/advanced/templates.md`. PR [#11620](https://github.com/tiangolo/fastapi/pull/11620) by [@chaoless](https://github.com/chaoless).
* 🌐 Add Turkish translation for `docs/tr/docs/deployment/index.md`. PR [#11605](https://github.com/tiangolo/fastapi/pull/11605) by [@hasansezertasan](https://github.com/hasansezertasan).
* 🌐 Add Turkish translation for `docs/tr/docs/tutorial/static-files.md`. PR [#11599](https://github.com/tiangolo/fastapi/pull/11599) by [@hasansezertasan](https://github.com/hasansezertasan).
* 🌐 Polish translation for `docs/pl/docs/fastapi-people.md`. PR [#10196](https://github.com/tiangolo/fastapi/pull/10196) by [@isulim](https://github.com/isulim).
* 🌐 Add Turkish translation for `docs/tr/docs/advanced/wsgi.md`. PR [#11575](https://github.com/tiangolo/fastapi/pull/11575) by [@hasansezertasan](https://github.com/hasansezertasan).
* 🌐 Add Turkish translation for `docs/tr/docs/tutorial/cookie-params.md`. PR [#11561](https://github.com/tiangolo/fastapi/pull/11561) by [@hasansezertasan](https://github.com/hasansezertasan).
* 🌐 Add Russian translation for `docs/ru/docs/about/index.md`. PR [#10961](https://github.com/tiangolo/fastapi/pull/10961) by [@s111d](https://github.com/s111d).
* 🌐 Update Chinese translation for `docs/zh/docs/tutorial/sql-databases.md`. PR [#11539](https://github.com/tiangolo/fastapi/pull/11539) by [@chaoless](https://github.com/chaoless).
* 🌐 Add Chinese translation for `docs/zh/docs/how-to/configure-swagger-ui.md`. PR [#11501](https://github.com/tiangolo/fastapi/pull/11501) by [@Lucas-lyh](https://github.com/Lucas-lyh).
@ -22,6 +44,8 @@ hide:
### Internal
* 👥 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).
* 👷 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 download artifact GitHub Action. PR [#11562](https://github.com/tiangolo/fastapi/pull/11562) by [@tiangolo](https://github.com/tiangolo).
* 👷 Update GitHub actions to download and upload artifacts to v4, for docs and coverage. PR [#11550](https://github.com/tiangolo/fastapi/pull/11550) by [@tamird](https://github.com/tamird).
@ -3868,7 +3892,7 @@ Note: all the previous parameters are still there, so it's still possible to dec
* New documentation about exceptions handlers:
* [Install custom exception handlers](https://fastapi.tiangolo.com/tutorial/handling-errors/#install-custom-exception-handlers).
* [Override the default exception handlers](https://fastapi.tiangolo.com/tutorial/handling-errors/#override-the-default-exception-handlers).
* [Re-use **FastAPI's** exception handlers](https://fastapi.tiangolo.com/tutorial/handling-errors/#re-use-fastapis-exception-handlers).
* [Reuse **FastAPI's** exception handlers](https://fastapi.tiangolo.com/tutorial/handling-errors/#reuse-fastapis-exception-handlers).
* PR [#273](https://github.com/tiangolo/fastapi/pull/273).
* Fix support for *paths* in *path parameters* without needing explicit `Path(...)`.

View File

@ -55,7 +55,7 @@ Inside of your *path operation function*, pass your task function to the *backgr
Using `BackgroundTasks` also works with the dependency injection system, you can declare a parameter of type `BackgroundTasks` at multiple levels: in a *path operation function*, in a dependency (dependable), in a sub-dependency, etc.
**FastAPI** knows what to do in each case and how to re-use the same object, so that all the background tasks are merged together and are run in the background afterwards:
**FastAPI** knows what to do in each case and how to reuse the same object, so that all the background tasks are merged together and are run in the background afterwards:
=== "Python 3.10+"

View File

@ -107,7 +107,7 @@ These dependencies can `raise` exceptions, the same as normal dependencies:
And they can return values or not, the values won't be used.
So, you can re-use a normal dependency (that returns a value) you already use somewhere else, and even though the value won't be used, the dependency will be executed:
So, you can reuse a normal dependency (that returns a value) you already use somewhere else, and even though the value won't be used, the dependency will be executed:
=== "Python 3.9+"

View File

@ -157,7 +157,7 @@ query_extractor --> query_or_cookie_extractor --> read_query
If one of your dependencies is declared multiple times for the same *path operation*, for example, multiple dependencies have a common sub-dependency, **FastAPI** will know to call that sub-dependency only once per request.
And it will save the returned value in a <abbr title="A utility/system to store computed/generated values, to re-use them instead of computing them again.">"cache"</abbr> and pass it to all the "dependants" that need it in that specific request, instead of calling the dependency multiple times for the same request.
And it will save the returned value in a <abbr title="A utility/system to store computed/generated values, to reuse them instead of computing them again.">"cache"</abbr> and pass it to all the "dependants" that need it in that specific request, instead of calling the dependency multiple times for the same request.
In an advanced scenario where you know you need the dependency to be called at every step (possibly multiple times) in the same request instead of using the "cached" value, you can set the parameter `use_cache=False` when using `Depends`:

View File

@ -325,6 +325,6 @@ There are many other objects and models that will be automatically converted to
* Import `FastAPI`.
* Create an `app` instance.
* Write a **path operation decorator** (like `@app.get("/")`).
* Write a **path operation function** (like `def root(): ...` above).
* Run the development server (like `uvicorn main:app --reload`).
* Write a **path operation decorator** using decorators like `@app.get("/")`.
* Define a **path operation function**; for example, `def root(): ...`.
* Run the development server using the command `fastapi dev`.

View File

@ -248,12 +248,12 @@ In this example, to be able to have both `HTTPException`s in the same code, Star
from starlette.exceptions import HTTPException as StarletteHTTPException
```
### Re-use **FastAPI**'s exception handlers
### Reuse **FastAPI**'s exception handlers
If you want to use the exception along with the same default exception handlers from **FastAPI**, You can import and re-use the default exception handlers from `fastapi.exception_handlers`:
If you want to use the exception along with the same default exception handlers from **FastAPI**, You can import and reuse the default exception handlers from `fastapi.exception_handlers`:
```Python hl_lines="2-5 15 21"
{!../../../docs_src/handling_errors/tutorial006.py!}
```
In this example you are just `print`ing the error with a very expressive message, but you get the idea. You can use the exception and then just re-use the default exception handlers.
In this example you are just `print`ing the error with a very expressive message, but you get the idea. You can use the exception and then just reuse the default exception handlers.

View File

@ -92,11 +92,7 @@ For example, to declare a `title` metadata value for the path parameter `item_id
```
!!! note
A path parameter is always required as it has to be part of the path.
So, you should declare it with `...` to mark it as required.
Nevertheless, even if you declared it with `None` or set a default value, it would not affect anything, it would still be always required.
A path parameter is always required as it has to be part of the path. Even if you declared it with `None` or set a default value, it would not affect anything, it would still be always required.
## Order the parameters as you need

View File

@ -99,7 +99,7 @@ Now let's jump to the fun stuff. 🎉
## Add `Query` to `Annotated` in the `q` parameter
Now that we have this `Annotated` where we can put more metadata, add `Query` to it, and set the parameter `max_length` to 50:
Now that we have this `Annotated` where we can put more information (in this case some additional validation), add `Query` inside of `Annotated`, and set the parameter `max_length` to `50`:
=== "Python 3.10+"
@ -115,7 +115,11 @@ Now that we have this `Annotated` where we can put more metadata, add `Query` to
Notice that the default value is still `None`, so the parameter is still optional.
But now, having `Query(max_length=50)` inside of `Annotated`, we are telling FastAPI that we want it to extract this value from the query parameters (this would have been the default anyway 🤷) and that we want to have **additional validation** for this value (that's why we do this, to get the additional validation). 😎
But now, having `Query(max_length=50)` inside of `Annotated`, we are telling FastAPI that we want it to have **additional validation** for this value, we want it to have maximum 50 characters. 😎
!!! tip
Here we are using `Query()` because this is a **query parameter**. Later we will see others like `Path()`, `Body()`, `Header()`, and `Cookie()`, that also accept the same arguments as `Query()`.
FastAPI will now:

View File

@ -45,9 +45,11 @@ Copy the example in a file `main.py`:
## Run it
!!! info
First install <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a>.
The <a href="https://github.com/Kludex/python-multipart" class="external-link" target="_blank">`python-multipart`</a> package is automatically installed with **FastAPI** when you run the `pip install fastapi` command.
E.g. `pip install python-multipart`.
However, if you use the `pip install fastapi-slim` command, the `python-multipart` package is not included by default. To install it manually, use the following command:
`pip install python-multipart`
This is because **OAuth2** uses "form data" for sending the `username` and `password`.
@ -56,7 +58,7 @@ Run the example with:
<div class="termy">
```console
$ uvicorn main:app --reload
$ fastapi dev main.py
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```

View File

@ -26,28 +26,24 @@ After a week, the token will be expired and the user will not be authorized and
If you want to play with JWT tokens and see how they work, check <a href="https://jwt.io/" class="external-link" target="_blank">https://jwt.io</a>.
## Install `python-jose`
## Install `PyJWT`
We need to install `python-jose` to generate and verify the JWT tokens in Python:
We need to install `PyJWT` to generate and verify the JWT tokens in Python:
<div class="termy">
```console
$ pip install "python-jose[cryptography]"
$ pip install pyjwt
---> 100%
```
</div>
<a href="https://github.com/mpdavis/python-jose" class="external-link" target="_blank">Python-jose</a> requires a cryptographic backend as an extra.
!!! info
If you are planning to use digital signature algorithms like RSA or ECDSA, you should install the cryptography library dependency `pyjwt[crypto]`.
Here we are using the recommended one: <a href="https://cryptography.io/" class="external-link" target="_blank">pyca/cryptography</a>.
!!! tip
This tutorial previously used <a href="https://pyjwt.readthedocs.io/" class="external-link" target="_blank">PyJWT</a>.
But it was updated to use Python-jose instead as it provides all the features from PyJWT plus some extras that you might need later when building integrations with other tools.
You can read more about it in the <a href="https://pyjwt.readthedocs.io/en/latest/installation.html" class="external-link" target="_blank">PyJWT Installation docs</a>.
## Password hashing
@ -111,19 +107,19 @@ And another one to authenticate and return a user.
=== "Python 3.10+"
```Python hl_lines="7 48 55-56 59-60 69-75"
```Python hl_lines="8 49 56-57 60-61 70-76"
{!> ../../../docs_src/security/tutorial004_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="7 48 55-56 59-60 69-75"
```Python hl_lines="8 49 56-57 60-61 70-76"
{!> ../../../docs_src/security/tutorial004_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="7 49 56-57 60-61 70-76"
```Python hl_lines="8 50 57-58 61-62 71-77"
{!> ../../../docs_src/security/tutorial004_an.py!}
```
@ -132,7 +128,7 @@ And another one to authenticate and return a user.
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="6 47 54-55 58-59 68-74"
```Python hl_lines="7 48 55-56 59-60 69-75"
{!> ../../../docs_src/security/tutorial004_py310.py!}
```
@ -141,7 +137,7 @@ And another one to authenticate and return a user.
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="7 48 55-56 59-60 69-75"
```Python hl_lines="8 49 56-57 60-61 70-76"
{!> ../../../docs_src/security/tutorial004.py!}
```
@ -178,19 +174,19 @@ Create a utility function to generate a new access token.
=== "Python 3.10+"
```Python hl_lines="6 12-14 28-30 78-86"
```Python hl_lines="4 7 13-15 29-31 79-87"
{!> ../../../docs_src/security/tutorial004_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="6 12-14 28-30 78-86"
```Python hl_lines="4 7 13-15 29-31 79-87"
{!> ../../../docs_src/security/tutorial004_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="6 13-15 29-31 79-87"
```Python hl_lines="4 7 14-16 30-32 80-88"
{!> ../../../docs_src/security/tutorial004_an.py!}
```
@ -199,7 +195,7 @@ Create a utility function to generate a new access token.
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="5 11-13 27-29 77-85"
```Python hl_lines="3 6 12-14 28-30 78-86"
{!> ../../../docs_src/security/tutorial004_py310.py!}
```
@ -208,7 +204,7 @@ Create a utility function to generate a new access token.
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="6 12-14 28-30 78-86"
```Python hl_lines="4 7 13-15 29-31 79-87"
{!> ../../../docs_src/security/tutorial004.py!}
```
@ -222,19 +218,19 @@ If the token is invalid, return an HTTP error right away.
=== "Python 3.10+"
```Python hl_lines="89-106"
```Python hl_lines="90-107"
{!> ../../../docs_src/security/tutorial004_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="89-106"
```Python hl_lines="90-107"
{!> ../../../docs_src/security/tutorial004_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="90-107"
```Python hl_lines="91-108"
{!> ../../../docs_src/security/tutorial004_an.py!}
```
@ -243,7 +239,7 @@ If the token is invalid, return an HTTP error right away.
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="88-105"
```Python hl_lines="89-106"
{!> ../../../docs_src/security/tutorial004_py310.py!}
```
@ -252,7 +248,7 @@ If the token is invalid, return an HTTP error right away.
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="89-106"
```Python hl_lines="90-107"
{!> ../../../docs_src/security/tutorial004.py!}
```
@ -264,19 +260,19 @@ Create a real JWT access token and return it.
=== "Python 3.10+"
```Python hl_lines="117-132"
```Python hl_lines="118-133"
{!> ../../../docs_src/security/tutorial004_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="117-132"
```Python hl_lines="118-133"
{!> ../../../docs_src/security/tutorial004_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="118-133"
```Python hl_lines="119-134"
{!> ../../../docs_src/security/tutorial004_an.py!}
```
@ -285,7 +281,7 @@ Create a real JWT access token and return it.
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="114-129"
```Python hl_lines="115-130"
{!> ../../../docs_src/security/tutorial004_py310.py!}
```
@ -294,7 +290,7 @@ Create a real JWT access token and return it.
!!! tip
Prefer to use the `Annotated` version if possible.
```Python hl_lines="115-130"
```Python hl_lines="116-131"
{!> ../../../docs_src/security/tutorial004.py!}
```
@ -384,7 +380,7 @@ Many packages that simplify it a lot have to make many compromises with the data
It gives you all the flexibility to choose the ones that fit your project the best.
And you can use directly many well maintained and widely used packages like `passlib` and `python-jose`, because **FastAPI** doesn't require any complex mechanisms to integrate external packages.
And you can use directly many well maintained and widely used packages like `passlib` and `PyJWT`, because **FastAPI** doesn't require any complex mechanisms to integrate external packages.
But it provides you the tools to simplify the process as much as possible without compromising flexibility, robustness, or security.

View File

@ -76,6 +76,12 @@
<img class="sponsor-image" src="/img/sponsors/mongodb-banner.png" />
</a>
</div>
<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">
<span class="sponsor-badge">sponsor</span>
<img class="sponsor-image" src="/img/sponsors/kong-banner.png" />
</a>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,178 @@
# Ludzie FastAPI
FastAPI posiada wspaniałą społeczność, która jest otwarta dla ludzi z każdego środowiska.
## Twórca - Opienik
Cześć! 👋
To ja:
{% if people %}
<div class="user-list user-list-center">
{% for user in people.maintainers %}
<div class="user"><a href="{{ user.url }}" target="_blank"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Liczba odpowiedzi: {{ user.answers }}</div><div class="count">Pull Requesty: {{ user.prs }}</div></div>
{% endfor %}
</div>
{% endif %}
Jestem twórcą i opiekunem **FastAPI**. Możesz przeczytać więcej na ten temat w [Pomoc FastAPI - Uzyskaj pomoc - Skontaktuj się z autorem](help-fastapi.md#connect-with-the-author){.internal-link target=_blank}.
...Ale tutaj chcę pokazać Ci społeczność.
---
**FastAPI** otrzymuje wiele wsparcia od społeczności. Chciałbym podkreślić ich wkład.
To są ludzie, którzy:
* [Pomagają innym z pytaniami na GitHub](help-fastapi.md#help-others-with-questions-in-github){.internal-link target=_blank}.
* [Tworzą Pull Requesty](help-fastapi.md#create-a-pull-request){.internal-link target=_blank}.
* Oceniają Pull Requesty, [to szczególnie ważne dla tłumaczeń](contributing.md#translations){.internal-link target=_blank}.
Proszę o brawa dla nich. 👏 🙇
## Najaktywniejsi użytkownicy w zeszłym miesiącu
Oto niektórzy użytkownicy, którzy [pomagali innym w największej liczbie pytań na GitHubie](help-fastapi.md#help-others-with-questions-in-github){.internal-link target=_blank} podczas ostatniego miesiąca. ☕
{% if people %}
<div class="user-list user-list-center">
{% for user in people.last_month_active %}
<div class="user"><a href="{{ user.url }}" target="_blank"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Udzielonych odpowiedzi: {{ user.count }}</div></div>
{% endfor %}
</div>
{% endif %}
## Eksperci
Oto **eksperci FastAPI**. 🤓
To użytkownicy, którzy [pomogli innym z największa liczbą pytań na GitHubie](help-fastapi.md#help-others-with-questions-in-github){.internal-link target=_blank} od *samego początku*.
Poprzez pomoc wielu innym, udowodnili, że są ekspertami. ✨
{% if people %}
<div class="user-list user-list-center">
{% for user in people.experts %}
<div class="user"><a href="{{ user.url }}" target="_blank"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Udzielonych odpowiedzi: {{ user.count }}</div></div>
{% endfor %}
</div>
{% endif %}
## Najlepsi Kontrybutorzy
Oto **Najlepsi Kontrybutorzy**. 👷
Ci użytkownicy [stworzyli najwięcej Pull Requestów](help-fastapi.md#create-a-pull-request){.internal-link target=_blank}, które zostały *wcalone*.
Współtworzyli kod źródłowy, dokumentację, tłumaczenia itp. 📦
{% if people %}
<div class="user-list user-list-center">
{% for user in people.top_contributors %}
<div class="user"><a href="{{ user.url }}" target="_blank"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Pull Requesty: {{ user.count }}</div></div>
{% endfor %}
</div>
{% endif %}
Jest wielu więcej kontrybutorów (ponad setka), możesz zobaczyć ich wszystkich na stronie <a href="https://github.com/tiangolo/fastapi/graphs/contributors" class="external-link" target="_blank">Kontrybutorzy FastAPI na GitHub</a>. 👷
## Najlepsi Oceniajacy
Ci uzytkownicy są **Najlepszymi oceniającymi**. 🕵️
### Oceny Tłumaczeń
Ja mówię tylko kilkoma językami (i to niezbyt dobrze 😅). Zatem oceniający są tymi, którzy mają [**moc zatwierdzania tłumaczeń**](contributing.md#translations){.internal-link target=_blank} dokumentacji. Bez nich nie byłoby dokumentacji w kilku innych językach.
---
**Najlepsi Oceniający** 🕵️ przejrzeli więcej Pull Requestów, niż inni, zapewniając jakość kodu, dokumentacji, a zwłaszcza **tłumaczeń**.
{% if people %}
<div class="user-list user-list-center">
{% for user in people.top_reviewers %}
<div class="user"><a href="{{ user.url }}" target="_blank"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Liczba ocen: {{ user.count }}</div></div>
{% endfor %}
</div>
{% endif %}
## Sponsorzy
Oto **Sponsorzy**. 😎
Wspierają moją pracę nad **FastAPI** (i innymi), głównie poprzez <a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub Sponsors</a>.
{% if sponsors %}
{% if sponsors.gold %}
### Złoci Sponsorzy
{% for sponsor in sponsors.gold -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor %}
{% endif %}
{% if sponsors.silver %}
### Srebrni Sponsorzy
{% for sponsor in sponsors.silver -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor %}
{% endif %}
{% if sponsors.bronze %}
### Brązowi Sponsorzy
{% for sponsor in sponsors.bronze -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor %}
{% endif %}
{% endif %}
### Indywidualni Sponsorzy
{% if github_sponsors %}
{% for group in github_sponsors.sponsors %}
<div class="user-list user-list-center">
{% for user in group %}
{% if user.login not in sponsors_badge.logins %}
<div class="user"><a href="{{ user.url }}" target="_blank"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a></div>
{% endif %}
{% endfor %}
</div>
{% endfor %}
{% endif %}
## Techniczne szczegóły danych
Głównym celem tej strony jest podkreślenie wysiłku społeczności w pomaganiu innym.
Szczególnie włączając wysiłki, które są zwykle mniej widoczne, a w wielu przypadkach bardziej żmudne, tak jak pomaganie innym z pytaniami i ocenianie Pull Requestów z tłumaczeniami.
Dane są obliczane każdego miesiąca, możesz przeczytać <a href="https://github.com/tiangolo/fastapi/blob/master/.github/actions/people/app/main.py" class="external-link" target="_blank">kod źródłowy tutaj</a>.
Tutaj również podkreślam wkład od sponsorów.
Zastrzegam sobie prawo do aktualizacji algorytmu, sekcji, progów itp. (na wszelki wypadek 🤷).

View File

@ -0,0 +1,16 @@
# Gelişmiş Güvenlik
## Ek Özellikler
[Tutorial - User Guide: Security](../../tutorial/security/index.md){.internal-link target=_blank} sayfasında ele alınanların dışında güvenlikle ilgili bazı ek özellikler vardır.
!!! tip "İpucu"
Sonraki bölümler **mutlaka "gelişmiş" olmak zorunda değildir**.
Kullanım şeklinize bağlı olarak, çözümünüz bu bölümlerden birinde olabilir.
## Önce Öğreticiyi Okuyun
Sonraki bölümler [Tutorial - User Guide: Security](../../tutorial/security/index.md){.internal-link target=_blank} sayfasını okuduğunuzu varsayarak hazırlanmıştır.
Bu bölümler aynı kavramlara dayanır, ancak bazı ek işlevsellikler sağlar.

View File

@ -0,0 +1,12 @@
# WebSockets'i Test Etmek
WebSockets testi yapmak için `TestClient`'ı kullanabilirsiniz.
Bu işlem için, `TestClient`'ı bir `with` ifadesinde kullanarak WebSocket'e bağlanabilirsiniz:
```Python hl_lines="27-31"
{!../../../docs_src/app_testing/tutorial002.py!}
```
!!! note "Not"
Daha fazla detay için Starlette'in <a href="https://www.starlette.io/staticfiles/" class="external-link" target="_blank">Websockets'i Test Etmek</a> dokümantasyonunu inceleyin.

View File

@ -0,0 +1,37 @@
# WSGI - Flask, Django ve Daha Fazlasını FastAPI ile Kullanma
WSGI uygulamalarını [Sub Applications - Mounts](sub-applications.md){.internal-link target=_blank}, [Behind a Proxy](behind-a-proxy.md){.internal-link target=_blank} bölümlerinde gördüğünüz gibi bağlayabilirsiniz.
Bunun için `WSGIMiddleware` ile Flask, Django vb. WSGI uygulamanızı sarmalayabilir ve FastAPI'ya bağlayabilirsiniz.
## `WSGIMiddleware` Kullanımı
`WSGIMiddleware`'ı projenize dahil edin.
Ardından WSGI (örneğin Flask) uygulamanızı middleware ile sarmalayın.
Son olarak da bir yol altında bağlama işlemini gerçekleştirin.
```Python hl_lines="2-3 23"
{!../../../docs_src/wsgi/tutorial001.py!}
```
## Kontrol Edelim
Artık `/v1/` yolunun altındaki her istek Flask uygulaması tarafından işlenecektir.
Geri kalanı ise **FastAPI** tarafından işlenecektir.
Eğer uygulamanızı çalıştırıp <a href="http://localhost:8000/v1/" class="external-link" target="_blank">http://localhost:8000/v1/</a> adresine giderseniz, Flask'tan gelen yanıtı göreceksiniz:
```txt
Hello, World from Flask!
```
Eğer <a href="http://localhost:8000/v2/" class="external-link" target="_blank">http://localhost:8000/v2/</a> adresine giderseniz, FastAPI'dan gelen yanıtı göreceksiniz:
```JSON
{
"message": "Hello World"
}
```

View File

@ -0,0 +1,17 @@
# FastAPI Uygulamasını Bulut Sağlayıcılar Üzerinde Yayınlama
FastAPI uygulamasını yayınlamak için hemen hemen **herhangi bir bulut sağlayıcıyı** kullanabilirsiniz.
Büyük bulut sağlayıcıların çoğu FastAPI uygulamasını yayınlamak için kılavuzlara sahiptir.
## Bulut Sağlayıcılar - Sponsorlar
Bazı bulut sağlayıcılar ✨ [**FastAPI destekçileridir**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, bu FastAPI ve **ekosisteminin** sürekli ve sağlıklı bir şekilde **gelişmesini** sağlar.
Ayrıca, size **iyi servisler** sağlamakla kalmayıp, **iyi ve sağlıklı bir framework** olan FastAPI'a bağlılıklarını gösterir.
Bu hizmetleri denemek ve kılavuzlarını incelemek isteyebilirsiniz:
* <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://docs.withcoherence.com/docs/configuration/frameworks?utm_medium=advertising&utm_source=fastapi&utm_campaign=banner%20january%2024#fast-api-example" class="external-link" target="_blank">Coherence</a>

View File

@ -0,0 +1,21 @@
# Deployment (Yayınlama)
**FastAPI** uygulamasını deploy etmek oldukça kolaydır.
## Deployment Ne Anlama Gelir?
Bir uygulamayı **deploy** etmek (yayınlamak), uygulamayı **kullanıcılara erişilebilir hale getirmek** için gerekli adımları gerçekleştirmek anlamına gelir.
Bir **Web API** için bu süreç normalde uygulamayı **uzak bir makineye** yerleştirmeyi, iyi performans, kararlılık vb. özellikler sağlayan bir **sunucu programı** ile **kullanıcılarınızın** uygulamaya etkili ve kesintisiz bir şekilde **erişebilmesini** kapsar.
Bu, kodu sürekli olarak değiştirdiğiniz, hata alıp hata giderdiğiniz, geliştirme sunucusunu durdurup yeniden başlattığınız vb. **geliştirme** aşamalarının tam tersidir.
## Deployment Stratejileri
Kullanım durumunuza ve kullandığınız araçlara bağlı olarak bir kaç farklı yol izleyebilirsiniz.
Bir dizi araç kombinasyonunu kullanarak kendiniz **bir sunucu yayınlayabilirsiniz**, yayınlama sürecinin bir kısmını sizin için gerçekleştiren bir **bulut hizmeti** veya diğer olası seçenekleri kullanabilirsiniz.
**FastAPI** uygulamasını yayınlarken aklınızda bulundurmanız gereken ana kavramlardan bazılarını size göstereceğim (ancak bunların çoğu diğer web uygulamaları için de geçerlidir).
Sonraki bölümlerde akılda tutulması gereken diğer ayrıntıları ve yayınlama tekniklerinden bazılarını göreceksiniz. ✨

View File

@ -0,0 +1,39 @@
# Genel - Nasıl Yapılır - Tarifler
Bu sayfada genel ve sıkça sorulan sorular için dokümantasyonun diğer sayfalarına yönlendirmeler bulunmaktadır.
## Veri Filtreleme - Güvenlik
Döndürmeniz gereken veriden fazlasını döndürmediğinizden emin olmak için, [Tutorial - Response Model - Return Type](../tutorial/response-model.md){.internal-link target=_blank} sayfasını okuyun.
## Dokümantasyon Etiketleri - OpenAPI
*Yol operasyonlarınıza* etiketler ekleyerek dokümantasyon arayüzünde gruplar halinde görünmesini sağlamak için, [Tutorial - Path Operation Configurations - Tags](../tutorial/path-operation-configuration.md#tags){.internal-link target=_blank} sayfasını okuyun.
## Dokümantasyon Özeti ve Açıklaması - OpenAPI
*Yol operasyonlarınıza* özet ve açıklama ekleyip dokümantasyon arayüzünde görünmesini sağlamak için, [Tutorial - Path Operation Configurations - Summary and Description](../tutorial/path-operation-configuration.md#summary-and-description){.internal-link target=_blank} sayfasını okuyun.
## Yanıt Açıklaması Dokümantasyonu - OpenAPI
Dokümantasyon arayüzünde yer alan yanıt açıklamasını tanımlamak için, [Tutorial - Path Operation Configurations - Response description](../tutorial/path-operation-configuration.md#response-description){.internal-link target=_blank} sayfasını okuyun.
## *Yol Operasyonunu* Kullanımdan Kaldırma - OpenAPI
Bir *yol işlemi*ni kullanımdan kaldırmak ve bunu dokümantasyon arayüzünde göstermek için, [Tutorial - Path Operation Configurations - Deprecation](../tutorial/path-operation-configuration.md#deprecate-a-path-operation){.internal-link target=_blank} sayfasını okuyun.
## Herhangi Bir Veriyi JSON Uyumlu Hale Getirme
Herhangi bir veriyi JSON uyumlu hale getirmek için, [Tutorial - JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank} sayfasını okuyun.
## OpenAPI Meta Verileri - Dokümantasyon
OpenAPI şemanıza lisans, sürüm, iletişim vb. meta veriler eklemek için, [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md){.internal-link target=_blank} sayfasını okuyun.
## OpenAPI Bağlantı Özelleştirme
OpenAPI bağlantısını özelleştirmek (veya kaldırmak) için, [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md#openapi-url){.internal-link target=_blank} sayfasını okuyun.
## OpenAPI Dokümantasyon Bağlantıları
Dokümantasyonu arayüzünde kullanılan bağlantıları güncellemek için, [Tutorial - Metadata and Docs URLs](../tutorial/metadata.md#docs-urls){.internal-link target=_blank} sayfasını okuyun.

View File

@ -0,0 +1,97 @@
# Çerez (Cookie) Parametreleri
`Query` (Sorgu) ve `Path` (Yol) parametrelerini tanımladığınız şekilde çerez parametreleri tanımlayabilirsiniz.
## Import `Cookie`
Öncelikle, `Cookie`'yi projenize dahil edin:
=== "Python 3.10+"
```Python hl_lines="3"
{!> ../../../docs_src/cookie_params/tutorial001_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="3"
{!> ../../../docs_src/cookie_params/tutorial001_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="3"
{!> ../../../docs_src/cookie_params/tutorial001_an.py!}
```
=== "Python 3.10+ non-Annotated"
!!! tip "İpucu"
Mümkün mertebe 'Annotated' sınıfını kullanmaya çalışın.
```Python hl_lines="1"
{!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip "İpucu"
Mümkün mertebe 'Annotated' sınıfını kullanmaya çalışın.
```Python hl_lines="3"
{!> ../../../docs_src/cookie_params/tutorial001.py!}
```
## `Cookie` Parametrelerini Tanımlayın
Çerez parametrelerini `Path` veya `Query` tanımlaması yapar gibi tanımlayın.
İlk değer varsayılan değerdir; tüm ekstra doğrulama veya belirteç parametrelerini kullanabilirsiniz:
=== "Python 3.10+"
```Python hl_lines="9"
{!> ../../../docs_src/cookie_params/tutorial001_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="9"
{!> ../../../docs_src/cookie_params/tutorial001_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="10"
{!> ../../../docs_src/cookie_params/tutorial001_an.py!}
```
=== "Python 3.10+ non-Annotated"
!!! tip "İpucu"
Mümkün mertebe 'Annotated' sınıfını kullanmaya çalışın.
```Python hl_lines="7"
{!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
```
=== "Python 3.8+ non-Annotated"
!!! tip "İpucu"
Mümkün mertebe 'Annotated' sınıfını kullanmaya çalışın.
```Python hl_lines="9"
{!> ../../../docs_src/cookie_params/tutorial001.py!}
```
!!! note "Teknik Detaylar"
`Cookie` sınıfı `Path` ve `Query` sınıflarının kardeşidir. Diğerleri gibi `Param` sınıfını miras alan bir sınıftır.
Ancak `fastapi`'dan projenize dahil ettiğiniz `Query`, `Path`, `Cookie` ve diğerleri aslında özel sınıflar döndüren birer fonksiyondur.
!!! info "Bilgi"
Çerez tanımlamak için `Cookie` sınıfını kullanmanız gerekmektedir, aksi taktirde parametreler sorgu parametreleri olarak yorumlanır.
## Özet
Çerez tanımlamalarını `Cookie` sınıfını kullanarak `Query` ve `Path` tanımlar gibi tanımlayın.

View File

@ -0,0 +1,39 @@
# Statik Dosyalar
`StaticFiles`'ı kullanarak statik dosyaları bir yol altında sunabilirsiniz.
## `StaticFiles` Kullanımı
* `StaticFiles` sınıfını projenize dahil edin.
* Bir `StaticFiles()` örneğini belirli bir yola bağlayın.
```Python hl_lines="2 6"
{!../../../docs_src/static_files/tutorial001.py!}
```
!!! note "Teknik Detaylar"
Projenize dahil etmek için `from starlette.staticfiles import StaticFiles` kullanabilirsiniz.
**FastAPI**, geliştiricilere kolaylık sağlamak amacıyla `starlette.staticfiles`'ı `fastapi.staticfiles` olarak sağlar. Ancak `StaticFiles` sınıfı aslında doğrudan Starlette'den gelir.
### Bağlama (Mounting) Nedir?
"Bağlamak", belirli bir yola tamamen "bağımsız" bir uygulama eklemek anlamına gelir ve ardından tüm alt yollara gelen istekler bu uygulama tarafından işlenir.
Bu, bir `APIRouter` kullanmaktan farklıdır çünkü bağlanmış bir uygulama tamamen bağımsızdır. Ana uygulamanızın OpenAPI ve dokümanlar, bağlanmış uygulamadan hiçbir şey içermez, vb.
[Advanced User Guide](../advanced/index.md){.internal-link target=_blank} bölümünde daha fazla bilgi edinebilirsiniz.
## Detaylar
`"/static"` ifadesi, bu "alt uygulamanın" "bağlanacağı" alt yolu belirtir. Bu nedenle, `"/static"` ile başlayan her yol, bu uygulama tarafından işlenir.
`directory="static"` ifadesi, statik dosyalarınızı içeren dizinin adını belirtir.
`name="static"` ifadesi, alt uygulamanın **FastAPI** tarafından kullanılacak ismini belirtir.
Bu parametrelerin hepsi "`static`"den farklı olabilir, bunları kendi uygulamanızın ihtiyaçlarına göre belirleyebilirsiniz.
## Daha Fazla Bilgi
Daha fazla detay ve seçenek için <a href="https://www.starlette.io/staticfiles/" class="external-link" target="_blank">Starlette'in Statik Dosyalar hakkındaki dokümantasyonunu</a> incelleyin.

View File

@ -20,24 +20,12 @@ $ pip install jinja2
</div>
如需使用静态文件,还要安装 `aiofiles`
<div class="termy">
```console
$ pip install aiofiles
---> 100%
```
</div>
## 使用 `Jinja2Templates`
* 导入 `Jinja2Templates`
* 创建可复用的 `templates` 对象
* 在返回模板的*路径操作*中声明 `Request` 参数
* 使用 `templates` 渲染并返回 `TemplateResponse` 以键值对方式在 Jinja2 的 **context** 中传递 `request`
* 使用 `templates` 渲染并返回 `TemplateResponse` 传递模板的名称、request对象以及一个包含多个键值对用于Jinja2模板的"context"字典,
```Python hl_lines="4 11 15-16"
{!../../../docs_src/templates/tutorial001.py!}
@ -45,7 +33,8 @@ $ pip install aiofiles
!!! note "笔记"
注意,必须为 Jinja2 以键值对方式在上下文中传递 `request`。因此,还要在*路径操作*中声明。
在FastAPI 0.108.0Starlette 0.29.0之前,`name`是第一个参数。
并且,在此之前,`request`对象是作为context的一部分以键值对的形式传递的。
!!! tip "提示"
@ -65,30 +54,68 @@ $ pip install aiofiles
{!../../../docs_src/templates/templates/item.html!}
```
它会显示从 **context** 字典中提取的 `id`
### 模板上下文
在包含如下语句的html中:
{% raw %}
```jinja
Item ID: {{ id }}
```
{% endraw %}
...这将显示你从"context"字典传递的 `id`:
```Python
{"request": request, "id": id}
{"id": id}
```
例如。当ID为 `42`时, 会渲染成:
```html
Item ID: 42
```
### 模板 `url_for` 参数
你还可以在模板内使用 `url_for()`,其参数与*路径操作函数*的参数相同.
所以,该部分:
{% raw %}
```jinja
<a href="{{ url_for('read_item', id=id) }}">
```
{% endraw %}
...将生成一个与处理*路径操作函数* `read_item(id=id)`的URL相同的链接
例如。当ID为 `42`时, 会渲染成:
```html
<a href="/items/42">
```
## 模板与静态文件
在模板内部使用 `url_for()`,例如,与挂载的 `StaticFiles` 一起使用。
你还可以在模板内部将 `url_for()`用于静态文件,例如你挂载的 `name="static"``StaticFiles`
```jinja hl_lines="4"
{!../../../docs_src/templates/templates/item.html!}
```
本例中,使用 `url_for()` 为模板添加 CSS 文件 `static/styles.css` 链接:
本例中,它将链接到 `static/styles.css`中的CSS文件
```CSS hl_lines="4"
{!../../../docs_src/templates/static/styles.css!}
```
因为使用了 `StaticFiles` **FastAPI** 应用自动提供位于 URL `/static/styles.css`
的 CSS 文件。
因为使用了 `StaticFiles` **FastAPI** 应用会自动提供位于 URL `/static/styles.css`的 CSS 文件。
## 更多说明
包括测试模板等更多详情,请参阅 <a href="https://www.starlette.io/templates/" class="external-link" target="_blank">Starlette 官档 - 模板</a>
包括测试模板等更多详情,请参阅 <a href="https://www.starlette.io/templates/" class="external-link" target="_blank">Starlette 官方文档 - 模板</a>

View File

@ -14,8 +14,8 @@ async def custom_swagger_ui_html():
openapi_url=app.openapi_url,
title=app.title + " - Swagger UI",
oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,
swagger_js_url="https://unpkg.com/swagger-ui-dist@5.9.0/swagger-ui-bundle.js",
swagger_css_url="https://unpkg.com/swagger-ui-dist@5.9.0/swagger-ui.css",
swagger_js_url="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js",
swagger_css_url="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css",
)

View File

@ -1,9 +1,10 @@
from datetime import datetime, timedelta, timezone
from typing import Union
import jwt
from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from jose import JWTError, jwt
from jwt.exceptions import InvalidTokenError
from passlib.context import CryptContext
from pydantic import BaseModel
@ -98,7 +99,7 @@ async def get_current_user(token: str = Depends(oauth2_scheme)):
if username is None:
raise credentials_exception
token_data = TokenData(username=username)
except JWTError:
except InvalidTokenError:
raise credentials_exception
user = get_user(fake_users_db, username=token_data.username)
if user is None:

View File

@ -1,9 +1,10 @@
from datetime import datetime, timedelta, timezone
from typing import Union
import jwt
from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from jose import JWTError, jwt
from jwt.exceptions import InvalidTokenError
from passlib.context import CryptContext
from pydantic import BaseModel
from typing_extensions import Annotated
@ -99,7 +100,7 @@ async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]):
if username is None:
raise credentials_exception
token_data = TokenData(username=username)
except JWTError:
except InvalidTokenError:
raise credentials_exception
user = get_user(fake_users_db, username=token_data.username)
if user is None:

View File

@ -1,9 +1,10 @@
from datetime import datetime, timedelta, timezone
from typing import Annotated
import jwt
from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from jose import JWTError, jwt
from jwt.exceptions import InvalidTokenError
from passlib.context import CryptContext
from pydantic import BaseModel
@ -98,7 +99,7 @@ async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]):
if username is None:
raise credentials_exception
token_data = TokenData(username=username)
except JWTError:
except InvalidTokenError:
raise credentials_exception
user = get_user(fake_users_db, username=token_data.username)
if user is None:

View File

@ -1,9 +1,10 @@
from datetime import datetime, timedelta, timezone
from typing import Annotated, Union
import jwt
from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from jose import JWTError, jwt
from jwt.exceptions import InvalidTokenError
from passlib.context import CryptContext
from pydantic import BaseModel
@ -98,7 +99,7 @@ async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]):
if username is None:
raise credentials_exception
token_data = TokenData(username=username)
except JWTError:
except InvalidTokenError:
raise credentials_exception
user = get_user(fake_users_db, username=token_data.username)
if user is None:

View File

@ -1,8 +1,9 @@
from datetime import datetime, timedelta, timezone
import jwt
from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from jose import JWTError, jwt
from jwt.exceptions import InvalidTokenError
from passlib.context import CryptContext
from pydantic import BaseModel
@ -97,7 +98,7 @@ async def get_current_user(token: str = Depends(oauth2_scheme)):
if username is None:
raise credentials_exception
token_data = TokenData(username=username)
except JWTError:
except InvalidTokenError:
raise credentials_exception
user = get_user(fake_users_db, username=token_data.username)
if user is None:

View File

@ -1,13 +1,14 @@
from datetime import datetime, timedelta, timezone
from typing import List, Union
import jwt
from fastapi import Depends, FastAPI, HTTPException, Security, status
from fastapi.security import (
OAuth2PasswordBearer,
OAuth2PasswordRequestForm,
SecurityScopes,
)
from jose import JWTError, jwt
from jwt.exceptions import InvalidTokenError
from passlib.context import CryptContext
from pydantic import BaseModel, ValidationError
@ -120,7 +121,7 @@ async def get_current_user(
raise credentials_exception
token_scopes = payload.get("scopes", [])
token_data = TokenData(scopes=token_scopes, username=username)
except (JWTError, ValidationError):
except (InvalidTokenError, ValidationError):
raise credentials_exception
user = get_user(fake_users_db, username=token_data.username)
if user is None:

View File

@ -1,13 +1,14 @@
from datetime import datetime, timedelta, timezone
from typing import List, Union
import jwt
from fastapi import Depends, FastAPI, HTTPException, Security, status
from fastapi.security import (
OAuth2PasswordBearer,
OAuth2PasswordRequestForm,
SecurityScopes,
)
from jose import JWTError, jwt
from jwt.exceptions import InvalidTokenError
from passlib.context import CryptContext
from pydantic import BaseModel, ValidationError
from typing_extensions import Annotated
@ -121,7 +122,7 @@ async def get_current_user(
raise credentials_exception
token_scopes = payload.get("scopes", [])
token_data = TokenData(scopes=token_scopes, username=username)
except (JWTError, ValidationError):
except (InvalidTokenError, ValidationError):
raise credentials_exception
user = get_user(fake_users_db, username=token_data.username)
if user is None:

View File

@ -1,13 +1,14 @@
from datetime import datetime, timedelta, timezone
from typing import Annotated
import jwt
from fastapi import Depends, FastAPI, HTTPException, Security, status
from fastapi.security import (
OAuth2PasswordBearer,
OAuth2PasswordRequestForm,
SecurityScopes,
)
from jose import JWTError, jwt
from jwt.exceptions import InvalidTokenError
from passlib.context import CryptContext
from pydantic import BaseModel, ValidationError
@ -120,7 +121,7 @@ async def get_current_user(
raise credentials_exception
token_scopes = payload.get("scopes", [])
token_data = TokenData(scopes=token_scopes, username=username)
except (JWTError, ValidationError):
except (InvalidTokenError, ValidationError):
raise credentials_exception
user = get_user(fake_users_db, username=token_data.username)
if user is None:

View File

@ -1,13 +1,14 @@
from datetime import datetime, timedelta, timezone
from typing import Annotated, List, Union
import jwt
from fastapi import Depends, FastAPI, HTTPException, Security, status
from fastapi.security import (
OAuth2PasswordBearer,
OAuth2PasswordRequestForm,
SecurityScopes,
)
from jose import JWTError, jwt
from jwt.exceptions import InvalidTokenError
from passlib.context import CryptContext
from pydantic import BaseModel, ValidationError
@ -120,7 +121,7 @@ async def get_current_user(
raise credentials_exception
token_scopes = payload.get("scopes", [])
token_data = TokenData(scopes=token_scopes, username=username)
except (JWTError, ValidationError):
except (InvalidTokenError, ValidationError):
raise credentials_exception
user = get_user(fake_users_db, username=token_data.username)
if user is None:

View File

@ -1,12 +1,13 @@
from datetime import datetime, timedelta, timezone
import jwt
from fastapi import Depends, FastAPI, HTTPException, Security, status
from fastapi.security import (
OAuth2PasswordBearer,
OAuth2PasswordRequestForm,
SecurityScopes,
)
from jose import JWTError, jwt
from jwt.exceptions import InvalidTokenError
from passlib.context import CryptContext
from pydantic import BaseModel, ValidationError
@ -119,7 +120,7 @@ async def get_current_user(
raise credentials_exception
token_scopes = payload.get("scopes", [])
token_data = TokenData(scopes=token_scopes, username=username)
except (JWTError, ValidationError):
except (InvalidTokenError, ValidationError):
raise credentials_exception
user = get_user(fake_users_db, username=token_data.username)
if user is None:

View File

@ -1,13 +1,14 @@
from datetime import datetime, timedelta, timezone
from typing import Union
import jwt
from fastapi import Depends, FastAPI, HTTPException, Security, status
from fastapi.security import (
OAuth2PasswordBearer,
OAuth2PasswordRequestForm,
SecurityScopes,
)
from jose import JWTError, jwt
from jwt.exceptions import InvalidTokenError
from passlib.context import CryptContext
from pydantic import BaseModel, ValidationError
@ -120,7 +121,7 @@ async def get_current_user(
raise credentials_exception
token_scopes = payload.get("scopes", [])
token_data = TokenData(scopes=token_scopes, username=username)
except (JWTError, ValidationError):
except (InvalidTokenError, ValidationError):
raise credentials_exception
user = get_user(fake_users_db, username=token_data.username)
if user is None:

View File

@ -902,7 +902,7 @@ class FastAPI(Starlette):
A state object for the application. This is the same object for the
entire application, it doesn't change from request to request.
You normally woudln't use this in FastAPI, for most of the cases you
You normally wouldn't use this in FastAPI, for most of the cases you
would instead use FastAPI dependencies.
This is simply inherited from Starlette.

View File

@ -53,7 +53,7 @@ def get_swagger_ui_html(
It is normally set to a CDN URL.
"""
),
] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5.9.0/swagger-ui-bundle.js",
] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js",
swagger_css_url: Annotated[
str,
Doc(
@ -63,7 +63,7 @@ def get_swagger_ui_html(
It is normally set to a CDN URL.
"""
),
] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5.9.0/swagger-ui.css",
] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css",
swagger_favicon_url: Annotated[
str,
Doc(

View File

@ -11,7 +11,7 @@ sqlalchemy >=1.3.18,<1.4.43
databases[sqlite] >=0.3.2,<0.7.0
flask >=1.1.2,<3.0.0
anyio[trio] >=3.2.1,<4.0.0
python-jose[cryptography] >=3.3.0,<4.0.0
PyJWT==2.8.0
pyyaml >=5.3.1,<7.0.0
passlib[bcrypt] >=1.7.2,<2.0.0

View File

@ -20,10 +20,8 @@ def client():
def test_swagger_ui_html(client: TestClient):
response = client.get("/docs")
assert response.status_code == 200, response.text
assert (
"https://unpkg.com/swagger-ui-dist@5.9.0/swagger-ui-bundle.js" in response.text
)
assert "https://unpkg.com/swagger-ui-dist@5.9.0/swagger-ui.css" in response.text
assert "https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js" in response.text
assert "https://unpkg.com/swagger-ui-dist@5/swagger-ui.css" in response.text
def test_swagger_ui_oauth2_redirect_html(client: TestClient):