Browse Source

Merge branch 'master' into feat/exception-on-duplicate-path

pull/5595/head
Irfanuddin Shafi Ahmed 2 years ago
committed by GitHub
parent
commit
ceb6f59c82
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 80
      docs/en/data/github_sponsors.yml
  2. 148
      docs/en/data/people.yml
  3. 2
      docs/en/docs/how-to/separate-openapi-schemas.md
  4. 10
      docs/en/docs/release-notes.md
  5. 2
      docs/en/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
  6. 2
      docs/en/docs/tutorial/handling-errors.md
  7. 4
      docs/en/docs/tutorial/schema-extra-example.md
  8. 412
      docs/uk/docs/alternatives.md
  9. 448
      docs/uk/docs/python-types.md
  10. 80
      docs/uk/docs/tutorial/index.md
  11. 333
      docs/vi/docs/tutorial/first-steps.md
  12. 80
      docs/vi/docs/tutorial/index.md
  13. 266
      docs/zh/docs/advanced/generate-clients.md
  14. 24
      fastapi/applications.py
  15. 3
      tests/test_openapi_examples.py

80
docs/en/data/github_sponsors.yml

@ -2,6 +2,9 @@ sponsors:
- - login: cryptapi
avatarUrl: https://avatars.githubusercontent.com/u/44925437?u=61369138589bc7fee6c417f3fbd50fbd38286cc4&v=4
url: https://github.com/cryptapi
- login: porter-dev
avatarUrl: https://avatars.githubusercontent.com/u/62078005?v=4
url: https://github.com/porter-dev
- login: fern-api
avatarUrl: https://avatars.githubusercontent.com/u/102944815?v=4
url: https://github.com/fern-api
@ -17,24 +20,21 @@ sponsors:
- - login: mikeckennedy
avatarUrl: https://avatars.githubusercontent.com/u/2035561?u=1bb18268bcd4d9249e1f783a063c27df9a84c05b&v=4
url: https://github.com/mikeckennedy
- login: ndimares
avatarUrl: https://avatars.githubusercontent.com/u/6267663?u=cfb27efde7a7212be8142abb6c058a1aeadb41b1&v=4
url: https://github.com/ndimares
- login: deta
avatarUrl: https://avatars.githubusercontent.com/u/47275976?v=4
url: https://github.com/deta
- login: deepset-ai
avatarUrl: https://avatars.githubusercontent.com/u/51827949?v=4
url: https://github.com/deepset-ai
- login: svix
avatarUrl: https://avatars.githubusercontent.com/u/80175132?v=4
url: https://github.com/svix
- login: databento-bot
avatarUrl: https://avatars.githubusercontent.com/u/98378480?u=494f679996e39427f7ddb1a7de8441b7c96fb670&v=4
url: https://github.com/databento-bot
- login: VincentParedes
avatarUrl: https://avatars.githubusercontent.com/u/103889729?v=4
url: https://github.com/VincentParedes
- - login: arcticfly
avatarUrl: https://avatars.githubusercontent.com/u/41524992?u=03c88529a86cf51f7a380e890d84d84c71468848&v=4
url: https://github.com/arcticfly
- - login: getsentry
avatarUrl: https://avatars.githubusercontent.com/u/1396951?v=4
url: https://github.com/getsentry
@ -89,18 +89,18 @@ sponsors:
- - login: povilasb
avatarUrl: https://avatars.githubusercontent.com/u/1213442?u=b11f58ed6ceea6e8297c9b310030478ebdac894d&v=4
url: https://github.com/povilasb
- login: mukulmantosh
avatarUrl: https://avatars.githubusercontent.com/u/15572034?u=006f0a33c0e15bb2de57474a2cf7d2f8ee05f5a0&v=4
url: https://github.com/mukulmantosh
- login: primer-io
avatarUrl: https://avatars.githubusercontent.com/u/62146168?v=4
url: https://github.com/primer-io
- - login: indeedeng
avatarUrl: https://avatars.githubusercontent.com/u/2905043?v=4
url: https://github.com/indeedeng
- login: iguit0
avatarUrl: https://avatars.githubusercontent.com/u/12905770?u=63a1a96d1e6c27d85c4f946b84836599de047f65&v=4
url: https://github.com/iguit0
- login: JacobKochems
avatarUrl: https://avatars.githubusercontent.com/u/41692189?u=a75f62ddc0d060ee6233a91e19c433d2687b8eb6&v=4
url: https://github.com/JacobKochems
- login: NateXVI
avatarUrl: https://avatars.githubusercontent.com/u/48195620?u=4bc8751ae50cb087c40c1fe811764aa070b9eea6&v=4
url: https://github.com/NateXVI
- - login: Kludex
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex
@ -200,12 +200,12 @@ sponsors:
- login: hiancdtrsnm
avatarUrl: https://avatars.githubusercontent.com/u/7343177?v=4
url: https://github.com/hiancdtrsnm
- login: Shackelford-Arden
avatarUrl: https://avatars.githubusercontent.com/u/7362263?v=4
url: https://github.com/Shackelford-Arden
- login: wdwinslow
avatarUrl: https://avatars.githubusercontent.com/u/11562137?u=dc01daafb354135603a263729e3d26d939c0c452&v=4
url: https://github.com/wdwinslow
- login: jsoques
avatarUrl: https://avatars.githubusercontent.com/u/12414216?u=620921d94196546cc8b9eae2cc4cbc3f95bab42f&v=4
url: https://github.com/jsoques
- login: joeds13
avatarUrl: https://avatars.githubusercontent.com/u/13631604?u=628eb122e08bef43767b3738752b883e8e7f6259&v=4
url: https://github.com/joeds13
@ -227,9 +227,6 @@ sponsors:
- login: Filimoa
avatarUrl: https://avatars.githubusercontent.com/u/21352040?u=0be845711495bbd7b756e13fcaeb8efc1ebd78ba&v=4
url: https://github.com/Filimoa
- login: LarryGF
avatarUrl: https://avatars.githubusercontent.com/u/26148349?u=431bb34d36d41c172466252242175281ae132152&v=4
url: https://github.com/LarryGF
- login: BrettskiPy
avatarUrl: https://avatars.githubusercontent.com/u/30988215?u=d8a94a67e140d5ee5427724b292cc52d8827087a&v=4
url: https://github.com/BrettskiPy
@ -239,6 +236,9 @@ sponsors:
- login: Leay15
avatarUrl: https://avatars.githubusercontent.com/u/32212558?u=c4aa9c1737e515959382a5515381757b1fd86c53&v=4
url: https://github.com/Leay15
- login: dvlpjrs
avatarUrl: https://avatars.githubusercontent.com/u/32254642?u=fbd6ad0324d4f1eb6231cf775be1c7bd4404e961&v=4
url: https://github.com/dvlpjrs
- login: ygorpontelo
avatarUrl: https://avatars.githubusercontent.com/u/32963605?u=35f7103f9c4c4c2589ae5737ee882e9375ef072e&v=4
url: https://github.com/ygorpontelo
@ -284,15 +284,15 @@ sponsors:
- login: DelfinaCare
avatarUrl: https://avatars.githubusercontent.com/u/83734439?v=4
url: https://github.com/DelfinaCare
- login: hbakri
avatarUrl: https://avatars.githubusercontent.com/u/92298226?u=36eee6d75db1272264d3ee92f1871f70b8917bd8&v=4
url: https://github.com/hbakri
- login: osawa-koki
avatarUrl: https://avatars.githubusercontent.com/u/94336223?u=59c6fe6945bcbbaff87b2a794238671b060620d2&v=4
url: https://github.com/osawa-koki
- login: pyt3h
avatarUrl: https://avatars.githubusercontent.com/u/99658549?v=4
url: https://github.com/pyt3h
- login: Dagmaara
avatarUrl: https://avatars.githubusercontent.com/u/115501964?v=4
url: https://github.com/Dagmaara
- - login: SebTota
avatarUrl: https://avatars.githubusercontent.com/u/25122511?v=4
url: https://github.com/SebTota
@ -329,6 +329,9 @@ sponsors:
- login: janfilips
avatarUrl: https://avatars.githubusercontent.com/u/870699?u=80702ec63f14e675cd4cdcc6ce3821d2ed207fd7&v=4
url: https://github.com/janfilips
- login: dodo5522
avatarUrl: https://avatars.githubusercontent.com/u/1362607?u=9bf1e0e520cccc547c046610c468ce6115bbcf9f&v=4
url: https://github.com/dodo5522
- login: WillHogan
avatarUrl: https://avatars.githubusercontent.com/u/1661551?u=7036c064cf29781470573865264ec8e60b6b809f&v=4
url: https://github.com/WillHogan
@ -374,9 +377,6 @@ sponsors:
- login: katnoria
avatarUrl: https://avatars.githubusercontent.com/u/7674948?u=09767eb13e07e09496c5fee4e5ce21d9eac34a56&v=4
url: https://github.com/katnoria
- login: mattwelke
avatarUrl: https://avatars.githubusercontent.com/u/7719209?u=80f02a799323b1472b389b836d95957c93a6d856&v=4
url: https://github.com/mattwelke
- login: harsh183
avatarUrl: https://avatars.githubusercontent.com/u/7780198?v=4
url: https://github.com/harsh183
@ -422,6 +422,9 @@ sponsors:
- login: jangia
avatarUrl: https://avatars.githubusercontent.com/u/17927101?u=9261b9bb0c3e3bb1ecba43e8915dc58d8c9a077e&v=4
url: https://github.com/jangia
- login: timzaz
avatarUrl: https://avatars.githubusercontent.com/u/19709244?u=e6658f6b0b188294ce2db20dad94a678fcea718d&v=4
url: https://github.com/timzaz
- login: shuheng-liu
avatarUrl: https://avatars.githubusercontent.com/u/22414322?u=813c45f30786c6b511b21a661def025d8f7b609e&v=4
url: https://github.com/shuheng-liu
@ -431,6 +434,9 @@ sponsors:
- login: kxzk
avatarUrl: https://avatars.githubusercontent.com/u/25046261?u=e185e58080090f9e678192cd214a14b14a2b232b&v=4
url: https://github.com/kxzk
- login: nisutec
avatarUrl: https://avatars.githubusercontent.com/u/25281462?u=e562484c451fdfc59053163f64405f8eb262b8b0&v=4
url: https://github.com/nisutec
- login: hoenie-ams
avatarUrl: https://avatars.githubusercontent.com/u/25708487?u=cda07434f0509ac728d9edf5e681117c0f6b818b&v=4
url: https://github.com/hoenie-ams
@ -450,7 +456,7 @@ sponsors:
avatarUrl: https://avatars.githubusercontent.com/u/33275230?u=eb223cad27017bb1e936ee9b429b450d092d0236&v=4
url: https://github.com/engineerjoe440
- login: bnkc
avatarUrl: https://avatars.githubusercontent.com/u/34930566?u=527044d90b5ebb7f8dad517db5da1f45253b774b&v=4
avatarUrl: https://avatars.githubusercontent.com/u/34930566?u=1a104991a2ea90bfe304bc0b9ef191c7e4891a0e&v=4
url: https://github.com/bnkc
- login: declon
avatarUrl: https://avatars.githubusercontent.com/u/36180226?v=4
@ -482,6 +488,15 @@ sponsors:
- login: 0417taehyun
avatarUrl: https://avatars.githubusercontent.com/u/63915557?u=47debaa860fd52c9b98c97ef357ddcec3b3fb399&v=4
url: https://github.com/0417taehyun
- login: romabozhanovgithub
avatarUrl: https://avatars.githubusercontent.com/u/67696229?u=e4b921eef096415300425aca249348f8abb78ad7&v=4
url: https://github.com/romabozhanovgithub
- login: mnicolleUTC
avatarUrl: https://avatars.githubusercontent.com/u/68548924?u=1fdd7f436bb1f4857c3415e62aa8fbc055fc1a76&v=4
url: https://github.com/mnicolleUTC
- login: mbukeRepo
avatarUrl: https://avatars.githubusercontent.com/u/70356088?u=e125069c6ac5c49355e2b3ca2aa66a445fc4cccd&v=4
url: https://github.com/mbukeRepo
- - login: ssbarnea
avatarUrl: https://avatars.githubusercontent.com/u/102495?u=b4bf6818deefe59952ac22fec6ed8c76de1b8f7c&v=4
url: https://github.com/ssbarnea
@ -494,21 +509,18 @@ sponsors:
- login: sadikkuzu
avatarUrl: https://avatars.githubusercontent.com/u/23168063?u=d179c06bb9f65c4167fcab118526819f8e0dac17&v=4
url: https://github.com/sadikkuzu
- login: ruizdiazever
avatarUrl: https://avatars.githubusercontent.com/u/29817086?u=2df54af55663d246e3a4dc8273711c37f1adb117&v=4
url: https://github.com/ruizdiazever
- login: samnimoh
avatarUrl: https://avatars.githubusercontent.com/u/33413170?u=147bc516be6cb647b28d7e3b3fea3a018a331145&v=4
url: https://github.com/samnimoh
- login: danburonline
avatarUrl: https://avatars.githubusercontent.com/u/34251194?u=2cad4388c1544e539ecb732d656e42fb07b4ff2d&v=4
url: https://github.com/danburonline
- login: iharshgor
avatarUrl: https://avatars.githubusercontent.com/u/35490011?u=2dea054476e752d9e92c9d71a9a7cc919b1c2f8e&v=4
url: https://github.com/iharshgor
- login: koalawangyang
avatarUrl: https://avatars.githubusercontent.com/u/40114367?u=3bb94010f0473b8d4c2edea5a8c1cab61e6a1b22&v=4
url: https://github.com/koalawangyang
- login: rwxd
avatarUrl: https://avatars.githubusercontent.com/u/40308458?u=cd04a39e3655923be4f25c2ba8a5a07b3da3230a&v=4
url: https://github.com/rwxd
- login: ThomasPalma1
avatarUrl: https://avatars.githubusercontent.com/u/66331874?u=5763f7402d784ba189b60d704ff5849b4d0a63fb&v=4
url: https://github.com/ThomasPalma1
- login: lodine-software
avatarUrl: https://avatars.githubusercontent.com/u/133536046?v=4
url: https://github.com/lodine-software

148
docs/en/data/people.yml

@ -1,16 +1,16 @@
maintainers:
- login: tiangolo
answers: 1849
prs: 466
answers: 1866
prs: 486
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=740f11212a731f56798f558ceddb0bd07642afa7&v=4
url: https://github.com/tiangolo
experts:
- login: Kludex
count: 463
count: 480
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex
- login: dmontagu
count: 239
count: 240
avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=540f30c937a6450812628b9592a1dfe91bbe148e&v=4
url: https://github.com/dmontagu
- login: Mause
@ -26,7 +26,7 @@ experts:
avatarUrl: https://avatars.githubusercontent.com/u/13659033?u=e8bea32d07a5ef72f7dde3b2079ceb714923ca05&v=4
url: https://github.com/JarroVGIT
- login: jgould22
count: 157
count: 164
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
url: https://github.com/jgould22
- login: euri10
@ -38,7 +38,7 @@ experts:
avatarUrl: https://avatars.githubusercontent.com/u/331403?v=4
url: https://github.com/phy25
- login: iudeen
count: 121
count: 122
avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4
url: https://github.com/iudeen
- login: raphaelauv
@ -61,34 +61,34 @@ experts:
count: 49
avatarUrl: https://avatars.githubusercontent.com/u/516999?u=437c0c5038558c67e887ccd863c1ba0f846c03da&v=4
url: https://github.com/sm-Fifteen
- login: insomnes
count: 45
avatarUrl: https://avatars.githubusercontent.com/u/16958893?u=f8be7088d5076d963984a21f95f44e559192d912&v=4
url: https://github.com/insomnes
- login: yinziyan1206
count: 45
avatarUrl: https://avatars.githubusercontent.com/u/37829370?u=da44ca53aefd5c23f346fab8e9fd2e108294c179&v=4
url: https://github.com/yinziyan1206
- login: acidjunk
- login: insomnes
count: 45
avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
url: https://github.com/acidjunk
avatarUrl: https://avatars.githubusercontent.com/u/16958893?u=f8be7088d5076d963984a21f95f44e559192d912&v=4
url: https://github.com/insomnes
- login: Dustyposa
count: 45
avatarUrl: https://avatars.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4
url: https://github.com/Dustyposa
- login: acidjunk
count: 45
avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
url: https://github.com/acidjunk
- login: adriangb
count: 44
avatarUrl: https://avatars.githubusercontent.com/u/1755071?u=612704256e38d6ac9cbed24f10e4b6ac2da74ecb&v=4
url: https://github.com/adriangb
- login: frankie567
count: 43
avatarUrl: https://avatars.githubusercontent.com/u/1144727?u=85c025e3fcc7bd79a5665c63ee87cdf8aae13374&v=4
url: https://github.com/frankie567
- login: odiseo0
count: 43
avatarUrl: https://avatars.githubusercontent.com/u/87550035?u=241a71f6b7068738b81af3e57f45ffd723538401&v=4
url: https://github.com/odiseo0
- login: frankie567
count: 43
avatarUrl: https://avatars.githubusercontent.com/u/1144727?u=c159fe047727aedecbbeeaa96a1b03ceb9d39add&v=4
url: https://github.com/frankie567
- login: includeamin
count: 40
avatarUrl: https://avatars.githubusercontent.com/u/11836741?u=8bd5ef7e62fe6a82055e33c4c0e0a7879ff8cfb6&v=4
@ -97,14 +97,14 @@ experts:
count: 37
avatarUrl: https://avatars.githubusercontent.com/u/5167622?u=de8f597c81d6336fcebc37b32dfd61a3f877160c&v=4
url: https://github.com/STeveShary
- login: chbndrhnns
count: 36
avatarUrl: https://avatars.githubusercontent.com/u/7534547?v=4
url: https://github.com/chbndrhnns
- login: krishnardt
count: 35
avatarUrl: https://avatars.githubusercontent.com/u/31960541?u=47f4829c77f4962ab437ffb7995951e41eeebe9b&v=4
url: https://github.com/krishnardt
- login: chbndrhnns
count: 35
avatarUrl: https://avatars.githubusercontent.com/u/7534547?v=4
url: https://github.com/chbndrhnns
- login: panla
count: 32
avatarUrl: https://avatars.githubusercontent.com/u/41326348?u=ba2fda6b30110411ecbf406d187907e2b420ac19&v=4
@ -117,26 +117,30 @@ experts:
count: 26
avatarUrl: https://avatars.githubusercontent.com/u/43723790?u=9bcce836bbce55835291c5b2ac93a4e311f4b3c3&v=4
url: https://github.com/dbanty
- login: n8sty
count: 25
avatarUrl: https://avatars.githubusercontent.com/u/2964996?v=4
url: https://github.com/n8sty
- login: wshayes
count: 25
avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
url: https://github.com/wshayes
- login: acnebs
count: 23
avatarUrl: https://avatars.githubusercontent.com/u/9054108?v=4
url: https://github.com/acnebs
- login: SirTelemak
count: 23
avatarUrl: https://avatars.githubusercontent.com/u/9435877?u=719327b7d2c4c62212456d771bfa7c6b8dbb9eac&v=4
url: https://github.com/SirTelemak
- login: acnebs
count: 23
avatarUrl: https://avatars.githubusercontent.com/u/9054108?v=4
url: https://github.com/acnebs
- login: rafsaf
count: 21
avatarUrl: https://avatars.githubusercontent.com/u/51059348?u=f8f0d6d6e90fac39fa786228158ba7f013c74271&v=4
avatarUrl: https://avatars.githubusercontent.com/u/51059348?u=5fe59a56e1f2f9ccd8005d71752a8276f133ae1a&v=4
url: https://github.com/rafsaf
- login: n8sty
- login: JavierSanchezCastro
count: 20
avatarUrl: https://avatars.githubusercontent.com/u/2964996?v=4
url: https://github.com/n8sty
avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
url: https://github.com/JavierSanchezCastro
- login: nsidnev
count: 20
avatarUrl: https://avatars.githubusercontent.com/u/22559461?u=a9cc3238217e21dc8796a1a500f01b722adb082c&v=4
@ -173,55 +177,51 @@ experts:
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/26334101?u=071c062d2861d3dd127f6b4a5258cd8ef55d4c50&v=4
url: https://github.com/jonatasoli
- login: ebottos94
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/100039558?u=e2c672da5a7977fd24d87ce6ab35f8bf5b1ed9fa&v=4
url: https://github.com/ebottos94
- login: dstlny
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/41964673?u=9f2174f9d61c15c6e3a4c9e3aeee66f711ce311f&v=4
url: https://github.com/dstlny
- login: abhint
- login: chrisK824
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/25699289?u=b5d219277b4d001ac26fb8be357fddd88c29d51b&v=4
url: https://github.com/abhint
avatarUrl: https://avatars.githubusercontent.com/u/79946379?u=03d85b22d696a58a9603e55fbbbe2de6b0f4face&v=4
url: https://github.com/chrisK824
- login: nymous
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/4216559?u=360a36fb602cded27273cbfc0afc296eece90662&v=4
url: https://github.com/nymous
- login: ghost
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/10137?u=b1951d34a583cf12ec0d3b0781ba19be97726318&v=4
url: https://github.com/ghost
- login: simondale00
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/33907262?v=4
url: https://github.com/simondale00
- login: jorgerpo
- login: abhint
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/12537771?u=7444d20019198e34911082780cc7ad73f2b97cb3&v=4
url: https://github.com/jorgerpo
avatarUrl: https://avatars.githubusercontent.com/u/25699289?u=b5d219277b4d001ac26fb8be357fddd88c29d51b&v=4
url: https://github.com/abhint
last_month_active:
- login: JavierSanchezCastro
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
url: https://github.com/JavierSanchezCastro
- login: Kludex
count: 24
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex
- login: jgould22
count: 17
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
url: https://github.com/jgould22
- login: arjwilliams
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/22227620?v=4
url: https://github.com/arjwilliams
- login: Ahmed-Abdou14
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/104530599?u=05365b155a1ff911532e8be316acfad2e0736f98&v=4
url: https://github.com/Ahmed-Abdou14
- login: iudeen
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4
url: https://github.com/iudeen
- login: mikeedjones
- login: romabozhanovgithub
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/67696229?u=e4b921eef096415300425aca249348f8abb78ad7&v=4
url: https://github.com/romabozhanovgithub
- login: n8sty
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/2964996?v=4
url: https://github.com/n8sty
- login: chrisK824
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/4087139?u=cc4a242896ac2fcf88a53acfaf190d0fe0a1f0c9&v=4
url: https://github.com/mikeedjones
avatarUrl: https://avatars.githubusercontent.com/u/79946379?u=03d85b22d696a58a9603e55fbbbe2de6b0f4face&v=4
url: https://github.com/chrisK824
top_contributors:
- login: waynerv
count: 25
@ -235,22 +235,22 @@ top_contributors:
count: 21
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex
- login: dmontagu
count: 17
avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=540f30c937a6450812628b9592a1dfe91bbe148e&v=4
url: https://github.com/dmontagu
- login: jaystone776
count: 17
avatarUrl: https://avatars.githubusercontent.com/u/11191137?u=299205a95e9b6817a43144a48b643346a5aac5cc&v=4
url: https://github.com/jaystone776
- login: dmontagu
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=540f30c937a6450812628b9592a1dfe91bbe148e&v=4
url: https://github.com/dmontagu
- login: Xewus
count: 14
avatarUrl: https://avatars.githubusercontent.com/u/85196001?u=f8e2dc7e5104f109cef944af79050ea8d1b8f914&v=4
url: https://github.com/Xewus
- login: euri10
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/1104190?u=321a2e953e6645a7d09b732786c7a8061e0f8a8b&v=4
url: https://github.com/euri10
- login: Xewus
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/85196001?u=f8e2dc7e5104f109cef944af79050ea8d1b8f914&v=4
url: https://github.com/Xewus
- login: mariacamilagl
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/11489395?u=4adb6986bf3debfc2b8216ae701f2bd47d73da7d&v=4
@ -360,6 +360,10 @@ top_reviewers:
count: 78
avatarUrl: https://avatars.githubusercontent.com/u/52716203?u=d7062cbc6eb7671d5dc9cc0e32a24ae335e0f225&v=4
url: https://github.com/yezz123
- login: iudeen
count: 53
avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4
url: https://github.com/iudeen
- login: tokusumi
count: 51
avatarUrl: https://avatars.githubusercontent.com/u/41147016?u=55010621aece725aa702270b54fed829b6a1fe60&v=4
@ -372,10 +376,6 @@ top_reviewers:
count: 47
avatarUrl: https://avatars.githubusercontent.com/u/59285379?v=4
url: https://github.com/Laineyzhang55
- login: iudeen
count: 46
avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4
url: https://github.com/iudeen
- login: ycd
count: 45
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=bba5af018423a2858d49309bed2a899bb5c34ac5&v=4
@ -385,7 +385,7 @@ top_reviewers:
avatarUrl: https://avatars.githubusercontent.com/u/24587499?u=e772190a051ab0eaa9c8542fcff1892471638f2b&v=4
url: https://github.com/cikay
- login: Xewus
count: 38
count: 39
avatarUrl: https://avatars.githubusercontent.com/u/85196001?u=f8e2dc7e5104f109cef944af79050ea8d1b8f914&v=4
url: https://github.com/Xewus
- login: JarroVGIT
@ -482,7 +482,7 @@ top_reviewers:
url: https://github.com/sh0nk
- login: peidrao
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/32584628?u=5b94b548ef0002ef3219d7c07ac0fac17c6201a2&v=4
avatarUrl: https://avatars.githubusercontent.com/u/32584628?u=a66902b40c13647d0ed0e573d598128240a4dd04&v=4
url: https://github.com/peidrao
- login: r0b2g1t
count: 13

2
docs/en/docs/how-to/separate-openapi-schemas.md

@ -160,7 +160,7 @@ If you interact with the docs and check the response, even though the code didn'
This means that it will **always have a value**, it's just that sometimes the value could be `None` (or `null` in JSON).
That means that, clients using your API don't have to check if the value exists or not, they can **asume the field will always be there**, but just that in some cases it will have the default value of `None`.
That means that, clients using your API don't have to check if the value exists or not, they can **assume the field will always be there**, but just that in some cases it will have the default value of `None`.
The way to describe this in OpenAPI, is to mark that field as **required**, because it will always be there.

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

@ -2,6 +2,16 @@
## Latest Changes
* 🌐 Add Vietnamese translations for `docs/vi/docs/tutorial/first-steps.md` and `docs/vi/docs/tutorial/index.md`. PR [#10088](https://github.com/tiangolo/fastapi/pull/10088) by [@magiskboy](https://github.com/magiskboy).
* ✏️ Fix typo in `docs/en/docs/tutorial/handling-errors.md`. PR [#10170](https://github.com/tiangolo/fastapi/pull/10170) by [@poupapaa](https://github.com/poupapaa).
* ✏️ Fix typos in comment in `fastapi/applications.py`. PR [#10045](https://github.com/tiangolo/fastapi/pull/10045) by [@AhsanSheraz](https://github.com/AhsanSheraz).
* ✏️ Fix typo in `docs/en/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md`. PR [#10172](https://github.com/tiangolo/fastapi/pull/10172) by [@ragul-kachiappan](https://github.com/ragul-kachiappan).
* 🌐 Add Ukrainian translation for `docs/uk/docs/alternatives.md`. PR [#10060](https://github.com/tiangolo/fastapi/pull/10060) by [@whysage](https://github.com/whysage).
* 🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/index.md`. PR [#10079](https://github.com/tiangolo/fastapi/pull/10079) by [@rostik1410](https://github.com/rostik1410).
* ✏️ Fix typos in `docs/en/docs/how-to/separate-openapi-schemas.md` and `docs/en/docs/tutorial/schema-extra-example.md`. PR [#10189](https://github.com/tiangolo/fastapi/pull/10189) by [@xzmeng](https://github.com/xzmeng).
* 🌐 Add Chinese translation for `docs/zh/docs/advanced/generate-clients.md`. PR [#9883](https://github.com/tiangolo/fastapi/pull/9883) by [@funny-cat-happy](https://github.com/funny-cat-happy).
* 👥 Update FastAPI People. PR [#10186](https://github.com/tiangolo/fastapi/pull/10186) by [@tiangolo](https://github.com/tiangolo).
* ✅ Add missing test for OpenAPI examples, it was missing in coverage. PR [#10188](https://github.com/tiangolo/fastapi/pull/10188) by [@tiangolo](https://github.com/tiangolo).
## 0.103.0

2
docs/en/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md

@ -35,7 +35,7 @@ It should be a `list` of `Depends()`:
{!> ../../../docs_src/dependencies/tutorial006.py!}
```
These dependencies will be executed/solved the same way normal dependencies. But their value (if they return any) won't be passed to your *path operation function*.
These dependencies will be executed/solved the same way as normal dependencies. But their value (if they return any) won't be passed to your *path operation function*.
!!! tip
Some editors check for unused function parameters, and show them as errors.

2
docs/en/docs/tutorial/handling-errors.md

@ -1,6 +1,6 @@
# Handling Errors
There are many situations in where you need to notify an error to a client that is using your API.
There are many situations in which you need to notify an error to a client that is using your API.
This client could be a browser with a frontend, a code from someone else, an IoT device, etc.

4
docs/en/docs/tutorial/schema-extra-example.md

@ -38,13 +38,13 @@ That extra info will be added as-is to the output **JSON Schema** for that model
In Pydantic version 2, you would use the attribute `model_config`, that takes a `dict` as described in <a href="https://docs.pydantic.dev/latest/usage/model_config/" class="external-link" target="_blank">Pydantic's docs: Model Config</a>.
You can set `"json_schema_extra"` with a `dict` containing any additonal data you would like to show up in the generated JSON Schema, including `examples`.
You can set `"json_schema_extra"` with a `dict` containing any additional data you would like to show up in the generated JSON Schema, including `examples`.
=== "Pydantic v1"
In Pydantic version 1, you would use an internal class `Config` and `schema_extra`, as described in <a href="https://docs.pydantic.dev/1.10/usage/schema/#schema-customization" class="external-link" target="_blank">Pydantic's docs: Schema customization</a>.
You can set `schema_extra` with a `dict` containing any additonal data you would like to show up in the generated JSON Schema, including `examples`.
You can set `schema_extra` with a `dict` containing any additional data you would like to show up in the generated JSON Schema, including `examples`.
!!! tip
You could use the same technique to extend the JSON Schema and add your own custom extra info.

412
docs/uk/docs/alternatives.md

@ -0,0 +1,412 @@
# Альтернативи, натхнення та порівняння
Що надихнуло на створення **FastAPI**, який він у порінянні з іншими альтернативами та чого він у них навчився.
## Вступ
**FastAPI** не існувало б, якби не попередні роботи інших.
Раніше було створено багато інструментів, які надихнули на його створення.
Я кілька років уникав створення нового фреймворку. Спочатку я спробував вирішити всі функції, охоплені **FastAPI**, використовуючи багато різних фреймворків, плагінів та інструментів.
Але в якийсь момент не було іншого виходу, окрім створення чогось, що надавало б усі ці функції, взявши найкращі ідеї з попередніх інструментів і поєднавши їх найкращим чином, використовуючи мовні функції, які навіть не були доступні раніше (Python 3.6+ підказки типів).
## Попередні інструменти
### <a href="https://www.djangoproject.com/" class="external-link" target="_blank">Django</a>
Це найпопулярніший фреймворк Python, який користується широкою довірою. Він використовується для створення таких систем, як Instagram.
Він відносно тісно пов’язаний з реляційними базами даних (наприклад, MySQL або PostgreSQL), тому мати базу даних NoSQL (наприклад, Couchbase, MongoDB, Cassandra тощо) як основний механізм зберігання не дуже просто.
Він був створений для створення HTML у серверній частині, а не для створення API, які використовуються сучасним інтерфейсом (як-от React, Vue.js і Angular) або іншими системами (як-от <abbr title="Internet of Things">IoT</abbr > пристрої), які спілкуються з ним.
### <a href="https://www.django-rest-framework.org/" class="external-link" target="_blank">Django REST Framework</a>
Фреймворк Django REST був створений як гнучкий інструментарій для створення веб-інтерфейсів API використовуючи Django в основі, щоб покращити його можливості API.
Його використовують багато компаній, включаючи Mozilla, Red Hat і Eventbrite.
Це був один із перших прикладів **автоматичної документації API**, і саме це була одна з перших ідей, яка надихнула на «пошук» **FastAPI**.
!!! Примітка
Django REST Framework створив Том Крісті. Той самий творець Starlette і Uvicorn, на яких базується **FastAPI**.
!!! Перегляньте "Надихнуло **FastAPI** на"
Мати автоматичний веб-інтерфейс документації API.
### <a href="https://flask.palletsprojects.com" class="external-link" target="_blank">Flask</a>
Flask — це «мікрофреймворк», він не включає інтеграцію бази даних, а також багато речей, які за замовчуванням є в Django.
Ця простота та гнучкість дозволяють використовувати бази даних NoSQL як основну систему зберігання даних.
Оскільки він дуже простий, він порівняно легкий та інтуїтивний для освоєння, хоча в деяких моментах документація стає дещо технічною.
Він також зазвичай використовується для інших програм, яким не обов’язково потрібна база даних, керування користувачами або будь-яка з багатьох функцій, які є попередньо вбудованими в Django. Хоча багато з цих функцій можна додати за допомогою плагінів.
Відокремлення частин було ключовою особливістю, яку я хотів зберегти, при цьому залишаючись «мікрофреймворком», який можна розширити, щоб охопити саме те, що потрібно.
Враховуючи простоту Flask, він здавався хорошим підходом для створення API. Наступним, що знайшов, був «Django REST Framework» для Flask.
!!! Переглянте "Надихнуло **FastAPI** на"
Бути мікрофреймоворком. Зробити легким комбінування та поєднання необхідних інструментів та частин.
Мати просту та легку у використанні систему маршрутизації.
### <a href="https://requests.readthedocs.io" class="external-link" target="_blank">Requests</a>
**FastAPI** насправді не є альтернативою **Requests**. Сфера їх застосування дуже різна.
Насправді цілком звична річ використовувати Requests *всередині* програми FastAPI.
Але все ж FastAPI черпав натхнення з Requests.
**Requests** — це бібліотека для *взаємодії* з API (як клієнт), а **FastAPI** — це бібліотека для *створення* API (як сервер).
Вони більш-менш знаходяться на протилежних кінцях, доповнюючи одна одну.
Requests мають дуже простий та інтуїтивно зрозумілий дизайн, дуже простий у використанні, з розумними параметрами за замовчуванням. Але в той же час він дуже потужний і налаштовується.
Ось чому, як сказано на офіційному сайті:
> Requests є одним із найбільш завантажуваних пакетів Python усіх часів
Використовувати його дуже просто. Наприклад, щоб виконати запит `GET`, ви повинні написати:
```Python
response = requests.get("http://example.com/some/url")
```
Відповідна операція *роуту* API FastAPI може виглядати так:
```Python hl_lines="1"
@app.get("/some/url")
def read_url():
return {"message": "Hello World"}
```
Зверніть увагу на схожість у `requests.get(...)` і `@app.get(...)`.
!!! Перегляньте "Надихнуло **FastAPI** на"
* Майте простий та інтуїтивно зрозумілий API.
* Використовуйте імена (операції) методів HTTP безпосередньо, простим та інтуїтивно зрозумілим способом.
* Розумні параметри за замовчуванням, але потужні налаштування.
### <a href="https://swagger.io/" class="external-link" target="_blank">Swagger</a> / <a href="https://github.com/OAI /OpenAPI-Specification/" class="external-link" target="_blank">OpenAPI</a>
Головною функцією, яку я хотів від Django REST Framework, була автоматична API документація.
Потім я виявив, що існує стандарт для документування API з використанням JSON (або YAML, розширення JSON) під назвою Swagger.
І вже був створений веб-інтерфейс користувача для Swagger API. Отже, можливість генерувати документацію Swagger для API дозволить використовувати цей веб-інтерфейс автоматично.
У якийсь момент Swagger було передано Linux Foundation, щоб перейменувати його на OpenAPI.
Тому, коли говорять про версію 2.0, прийнято говорити «Swagger», а про версію 3+ «OpenAPI».
!!! Перегляньте "Надихнуло **FastAPI** на"
Прийняти і використовувати відкритий стандарт для специфікацій API замість спеціальної схеми.
Інтегрувати інструменти інтерфейсу на основі стандартів:
* <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Інтерфейс Swagger</a>
* <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>
Ці два було обрано через те, що вони досить популярні та стабільні, але, виконавши швидкий пошук, ви можете знайти десятки додаткових альтернативних інтерфейсів для OpenAPI (які можна використовувати з **FastAPI**).
### Фреймворки REST для Flask
Існує кілька фреймворків Flask REST, але, витративши час і роботу на їх дослідження, я виявив, що багато з них припинено або залишено, з кількома постійними проблемами, які зробили їх непридатними.
### <a href="https://marshmallow.readthedocs.io/en/stable/" class="external-link" target="_blank">Marshmallow</a>
Однією з головних функцій, необхідних для систем API, є "<abbr title="також звана marshalling, conversion">серіалізація</abbr>", яка бере дані з коду (Python) і перетворює їх на щось, що можна надіслати через мережу. Наприклад, перетворення об’єкта, що містить дані з бази даних, на об’єкт JSON. Перетворення об’єктів `datetime` на строки тощо.
Іншою важливою функцією, необхідною для API, є перевірка даних, яка забезпечує дійсність даних за певними параметрами. Наприклад, що деяке поле є `int`, а не деяка випадкова строка. Це особливо корисно для вхідних даних.
Без системи перевірки даних вам довелося б виконувати всі перевірки вручну, у коді.
Marshmallow створено для забезпечення цих функцій. Це чудова бібліотека, і я часто нею користувався раніше.
Але він був створений до того, як існували підказки типу Python. Отже, щоб визначити кожну <abbr title="визначення того, як дані повинні бути сформовані">схему</abbr>, вам потрібно використовувати спеціальні утиліти та класи, надані Marshmallow.
!!! Перегляньте "Надихнуло **FastAPI** на"
Використовувати код для автоматичного визначення "схем", які надають типи даних і перевірку.
### <a href="https://webargs.readthedocs.io/en/latest/" class="external-link" target="_blank">Webargs</a>
Іншою важливою функцією, необхідною для API, є <abbr title="читання та перетворення даних Python">аналіз</abbr> даних із вхідних запитів.
Webargs — це інструмент, створений, щоб забезпечити це поверх кількох фреймворків, включаючи Flask.
Він використовує Marshmallow в основі для перевірки даних. І створений тими ж розробниками.
Це чудовий інструмент, і я також часто використовував його, перш ніж створити **FastAPI**.
!!! Інформація
Webargs був створений тими ж розробниками Marshmallow.
!!! Перегляньте "Надихнуло **FastAPI** на"
Мати автоматичну перевірку даних вхідного запиту.
### <a href="https://apispec.readthedocs.io/en/stable/" class="external-link" target="_blank">APISpec</a>
Marshmallow і Webargs забезпечують перевірку, аналіз і серіалізацію як плагіни.
Але документація досі відсутня. Потім було створено APISpec.
Це плагін для багатьох фреймворків (також є плагін для Starlette).
Принцип роботи полягає в тому, що ви пишете визначення схеми, використовуючи формат YAML, у docstring кожної функції, що обробляє маршрут.
І він генерує схеми OpenAPI.
Так це працює у Flask, Starlette, Responder тощо.
Але потім ми знову маємо проблему наявності мікросинтаксису всередині Python строки (великий YAML).
Редактор тут нічим не може допомогти. І якщо ми змінимо параметри чи схеми Marshmallow і забудемо також змінити цю строку документа YAML, згенерована схема буде застарілою.
!!! Інформація
APISpec був створений тими ж розробниками Marshmallow.
!!! Перегляньте "Надихнуло **FastAPI** на"
Підтримувати відкритий стандарт API, OpenAPI.
### <a href="https://flask-apispec.readthedocs.io/en/latest/" class="external-link" target="_blank">Flask-apispec</a>
Це плагін Flask, який об’єднує Webargs, Marshmallow і APISpec.
Він використовує інформацію з Webargs і Marshmallow для автоматичного створення схем OpenAPI за допомогою APISpec.
Це чудовий інструмент, дуже недооцінений. Він має бути набагато популярнішим, ніж багато плагінів Flask. Це може бути пов’язано з тим, що його документація надто стисла й абстрактна.
Це вирішило необхідність писати YAML (інший синтаксис) всередині рядків документів Python.
Ця комбінація Flask, Flask-apispec із Marshmallow і Webargs була моїм улюбленим бекенд-стеком до створення **FastAPI**.
Їі використання призвело до створення кількох генераторів повного стека Flask. Це основний стек, який я (та кілька зовнішніх команд) використовував досі:
* <a href="https://github.com/tiangolo/full-stack" class="external-link" target="_blank">https://github.com/tiangolo/full-stack</a>
* <a href="https://github.com/tiangolo/full-stack-flask-couchbase" class="external-link" target="_blank">https://github.com/tiangolo/full-stack-flask-couchbase</a>
* <a href="https://github.com/tiangolo/full-stack-flask-couchdb" class="external-link" target="_blank">https://github.com/tiangolo/full-stack-flask-couchdb</a>
І ці самі генератори повного стеку були основою [**FastAPI** генераторів проектів](project-generation.md){.internal-link target=_blank}.
!!! Інформація
Flask-apispec був створений тими ж розробниками Marshmallow.
!!! Перегляньте "Надихнуло **FastAPI** на"
Створення схеми OpenAPI автоматично з того самого коду, який визначає серіалізацію та перевірку.
### <a href="https://nestjs.com/" class="external-link" target="_blank">NestJS</a> (та <a href="https://angular.io/ " class="external-link" target="_blank">Angular</a>)
Це навіть не Python, NestJS — це фреймворк NodeJS JavaScript (TypeScript), натхненний Angular.
Це досягає чогось подібного до того, що можна зробити з Flask-apispec.
Він має інтегровану систему впровадження залежностей, натхненну Angular two. Він потребує попередньої реєстрації «injectables» (як і всі інші системи впровадження залежностей, які я знаю), тому це збільшує багатослівність та повторення коду.
Оскільки параметри описані за допомогою типів TypeScript (подібно до підказок типу Python), підтримка редактора досить хороша.
Але оскільки дані TypeScript не зберігаються після компіляції в JavaScript, вони не можуть покладатися на типи для визначення перевірки, серіалізації та документації одночасно. Через це та деякі дизайнерські рішення, щоб отримати перевірку, серіалізацію та автоматичну генерацію схеми, потрібно додати декоратори в багатьох місцях. Таким чином код стає досить багатослівним.
Він не дуже добре обробляє вкладені моделі. Отже, якщо тіло JSON у запиті є об’єктом JSON із внутрішніми полями, які, у свою чергу, є вкладеними об’єктами JSON, його неможливо належним чином задокументувати та перевірити.
!!! Перегляньте "Надихнуло **FastAPI** на"
Використовувати типи Python, щоб мати чудову підтримку редактора.
Мати потужну систему впровадження залежностей. Знайдіть спосіб звести до мінімуму повторення коду.
### <a href="https://sanic.readthedocs.io/en/latest/" class="external-link" target="_blank">Sanic</a>
Це був один із перших надзвичайно швидких фреймворків Python на основі `asyncio`. Він був дуже схожий на Flask.
!!! Примітка "Технічні деталі"
Він використовував <a href="https://github.com/MagicStack/uvloop" class="external-link" target="_blank">`uvloop`</a> замість стандартного циклу Python `asyncio`. Ось що зробило його таким швидким.
Це явно надихнуло Uvicorn і Starlette, які зараз швидші за Sanic у відкритих тестах.
!!! Перегляньте "Надихнуло **FastAPI** на"
Знайти спосіб отримати божевільну продуктивність.
Ось чому **FastAPI** базується на Starlette, оскільки це найшвидша доступна структура (перевірена тестами сторонніх розробників).
### <a href="https://falconframework.org/" class="external-link" target="_blank">Falcon</a>
Falcon — ще один високопродуктивний фреймворк Python, він розроблений як мінімальний і працює як основа інших фреймворків, таких як Hug.
Він розроблений таким чином, щоб мати функції, які отримують два параметри, один «запит» і один «відповідь». Потім ви «читаєте» частини запиту та «записуєте» частини у відповідь. Через такий дизайн неможливо оголосити параметри запиту та тіла за допомогою стандартних підказок типу Python як параметри функції.
Таким чином, перевірка даних, серіалізація та документація повинні виконуватися в коді, а не автоматично. Або вони повинні бути реалізовані як фреймворк поверх Falcon, як Hug. Така сама відмінність спостерігається в інших фреймворках, натхненних дизайном Falcon, що мають один об’єкт запиту та один об’єкт відповіді як параметри.
!!! Перегляньте "Надихнуло **FastAPI** на"
Знайти способи отримати чудову продуктивність.
Разом із Hug (оскільки Hug базується на Falcon) надихнув **FastAPI** оголосити параметр `response` у функціях.
Хоча у FastAPI це необов’язково, і використовується в основному для встановлення заголовків, файлів cookie та альтернативних кодів стану.
### <a href="https://moltenframework.com/" class="external-link" target="_blank">Molten</a>
Я відкрив для себе Molten на перших етапах створення **FastAPI**. І він має досить схожі ідеї:
* Базується на підказках типу Python.
* Перевірка та документація цих типів.
* Система впровадження залежностей.
Він не використовує перевірку даних, серіалізацію та бібліотеку документації сторонніх розробників, як Pydantic, він має свою власну. Таким чином, ці визначення типів даних не можна було б використовувати повторно так легко.
Це вимагає трохи більш докладних конфігурацій. І оскільки він заснований на WSGI (замість ASGI), він не призначений для використання високопродуктивних інструментів, таких як Uvicorn, Starlette і Sanic.
Система впровадження залежностей вимагає попередньої реєстрації залежностей, і залежності вирішуються на основі оголошених типів. Отже, неможливо оголосити більше ніж один «компонент», який надає певний тип.
Маршрути оголошуються в одному місці з використанням функцій, оголошених в інших місцях (замість використання декораторів, які можна розмістити безпосередньо поверх функції, яка обробляє кінцеву точку). Це ближче до того, як це робить Django, ніж до Flask (і Starlette). Він розділяє в коді речі, які відносно тісно пов’язані.
!!! Перегляньте "Надихнуло **FastAPI** на"
Визначити додаткові перевірки для типів даних, використовуючи значення "за замовчуванням" атрибутів моделі. Це покращує підтримку редактора, а раніше вона була недоступна в Pydantic.
Це фактично надихнуло оновити частини Pydantic, щоб підтримувати той самий стиль оголошення перевірки (всі ці функції вже доступні в Pydantic).
### <a href="https://www.hug.rest/" class="external-link" target="_blank">Hug</a>
Hug був одним із перших фреймворків, який реалізував оголошення типів параметрів API за допомогою підказок типу Python. Це була чудова ідея, яка надихнула інші інструменти зробити те саме.
Він використовував спеціальні типи у своїх оголошеннях замість стандартних типів Python, але це все одно був величезний крок вперед.
Це також був один із перших фреймворків, який генерував спеціальну схему, що оголошувала весь API у JSON.
Він не базувався на таких стандартах, як OpenAPI та JSON Schema. Тому було б непросто інтегрувати його з іншими інструментами, як-от Swagger UI. Але знову ж таки, це була дуже інноваційна ідея.
Він має цікаву незвичайну функцію: використовуючи ту саму структуру, можна створювати API, а також CLI.
Оскільки він заснований на попередньому стандарті для синхронних веб-фреймворків Python (WSGI), він не може працювати з Websockets та іншими речами, хоча він також має високу продуктивність.
!!! Інформація
Hug створив Тімоті Крослі, той самий творець <a href="https://github.com/timothycrosley/isort" class="external-link" target="_blank">`isort`</a>, чудовий інструмент для автоматичного сортування імпорту у файлах Python.
!!! Перегляньте "Надихнуло **FastAPI** на"
Hug надихнув частину APIStar і був одним із найбільш перспективних інструментів, поряд із APIStar.
Hug надихнув **FastAPI** на використання підказок типу Python для оголошення параметрів і автоматичного створення схеми, що визначає API.
Hug надихнув **FastAPI** оголосити параметр `response` у функціях для встановлення заголовків і файлів cookie.
### <a href="https://github.com/encode/apistar" class="external-link" target="_blank">APIStar</a> (<= 0,5)
Безпосередньо перед тим, як вирішити створити **FastAPI**, я знайшов сервер **APIStar**. Він мав майже все, що я шукав, і мав чудовий дизайн.
Це була одна з перших реалізацій фреймворку, що використовує підказки типу Python для оголошення параметрів і запитів, яку я коли-небудь бачив (до NestJS і Molten). Я знайшов його більш-менш одночасно з Hug. Але APIStar використовував стандарт OpenAPI.
Він мав автоматичну перевірку даних, серіалізацію даних і генерацію схеми OpenAPI на основі підказок того самого типу в кількох місцях.
Визначення схеми тіла не використовували ті самі підказки типу Python, як Pydantic, воно було трохи схоже на Marshmallow, тому підтримка редактора була б не такою хорошою, але все ж APIStar був найкращим доступним варіантом.
Він мав найкращі показники продуктивності на той час (перевершив лише Starlette).
Спочатку він не мав автоматичного веб-інтерфейсу документації API, але я знав, що можу додати до нього інтерфейс користувача Swagger.
Він мав систему введення залежностей. Він вимагав попередньої реєстрації компонентів, як і інші інструменти, розглянуті вище. Але все одно це була чудова функція.
Я ніколи не міг використовувати його в повноцінному проекті, оскільки він не мав інтеграції безпеки, тому я не міг замінити всі функції, які мав, генераторами повного стеку на основі Flask-apispec. У моїх невиконаних проектах я мав створити запит на вилучення, додавши цю функцію.
Але потім фокус проекту змінився.
Це вже не був веб-фреймворк API, оскільки творцю потрібно було зосередитися на Starlette.
Тепер APIStar — це набір інструментів для перевірки специфікацій OpenAPI, а не веб-фреймворк.
!!! Інформація
APIStar створив Том Крісті. Той самий хлопець, який створив:
* Django REST Framework
* Starlette (на якому базується **FastAPI**)
* Uvicorn (використовується Starlette і **FastAPI**)
!!! Перегляньте "Надихнуло **FastAPI** на"
Існувати.
Ідею оголошення кількох речей (перевірки даних, серіалізації та документації) за допомогою тих самих типів Python, які в той же час забезпечували чудову підтримку редактора, я вважав геніальною ідеєю.
І після тривалого пошуку подібної структури та тестування багатьох різних альтернатив, APIStar став найкращим доступним варіантом.
Потім APIStar перестав існувати як сервер, і було створено Starlette, який став новою кращою основою для такої системи. Це стало останнім джерелом натхнення для створення **FastAPI**. Я вважаю **FastAPI** «духовним спадкоємцем» APIStar, удосконалюючи та розширюючи функції, систему введення тексту та інші частини на основі досвіду, отриманого від усіх цих попередніх інструментів.
## Використовується **FastAPI**
### <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a>
Pydantic — це бібліотека для визначення перевірки даних, серіалізації та документації (за допомогою схеми JSON) на основі підказок типу Python.
Це робить його надзвичайно інтуїтивним.
Його можна порівняти з Marshmallow. Хоча він швидший за Marshmallow у тестах. Оскільки він базується на тих самих підказках типу Python, підтримка редактора чудова.
!!! Перегляньте "**FastAPI** використовує його для"
Виконання перевірки всіх даних, серіалізації даних і автоматичної документацію моделі (на основі схеми JSON).
Потім **FastAPI** бере ці дані схеми JSON і розміщує їх у OpenAPI, окремо від усіх інших речей, які він робить.
### <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a>
Starlette — це легкий фреймворк/набір інструментів <abbr title="The new standard for build asynchronous Python web">ASGI</abbr>, який ідеально підходить для створення високопродуктивних asyncio сервісів.
Він дуже простий та інтуїтивно зрозумілий. Його розроблено таким чином, щоб його можна було легко розширювати та мати модульні компоненти.
Він має:
* Серйозно вражаючу продуктивність.
* Підтримку WebSocket.
* Фонові завдання в процесі.
* Події запуску та завершення роботи.
* Тестового клієнта, побудований на HTTPX.
* CORS, GZip, статичні файли, потокові відповіді.
* Підтримку сеансів і файлів cookie.
* 100% покриття тестом.
* 100% анотовану кодову базу.
* Кілька жорстких залежностей.
Starlette наразі є найшвидшим фреймворком Python із перевірених. Перевершує лише Uvicorn, який є не фреймворком, а сервером.
Starlette надає всі основні функції веб-мікрофреймворку.
Але він не забезпечує автоматичної перевірки даних, серіалізації чи документації.
Це одна з головних речей, які **FastAPI** додає зверху, все на основі підказок типу Python (з використанням Pydantic). Це, а також система впровадження залежностей, утиліти безпеки, створення схеми OpenAPI тощо.
!!! Примітка "Технічні деталі"
ASGI — це новий «стандарт», який розробляється членами основної команди Django. Це ще не «стандарт Python» (PEP), хоча вони в процесі цього.
Тим не менш, він уже використовується як «стандарт» кількома інструментами. Це значно покращує сумісність, оскільки ви можете переключити Uvicorn на будь-який інший сервер ASGI (наприклад, Daphne або Hypercorn), або ви можете додати інструменти, сумісні з ASGI, як-от `python-socketio`.
!!! Перегляньте "**FastAPI** використовує його для"
Керування всіма основними веб-частинами. Додавання функцій зверху.
Сам клас `FastAPI` безпосередньо успадковує клас `Starlette`.
Отже, усе, що ви можете робити зі Starlette, ви можете робити це безпосередньо за допомогою **FastAPI**, оскільки це, по суті, Starlette на стероїдах.
### <a href="https://www.uvicorn.org/" class="external-link" target="_blank">Uvicorn</a>
Uvicorn — це блискавичний сервер ASGI, побудований на uvloop і httptools.
Це не веб-фреймворк, а сервер. Наприклад, він не надає інструментів для маршрутизації. Це те, що фреймворк на кшталт Starlette (або **FastAPI**) забезпечить поверх нього.
Це рекомендований сервер для Starlette і **FastAPI**.
!!! Перегляньте "**FastAPI** рекомендує це як"
Основний веб-сервер для запуску програм **FastAPI**.
Ви можете поєднати його з Gunicorn, щоб мати асинхронний багатопроцесний сервер.
Додаткову інформацію див. у розділі [Розгортання](deployment/index.md){.internal-link target=_blank}.
## Орієнтири та швидкість
Щоб зрозуміти, порівняти та побачити різницю між Uvicorn, Starlette і FastAPI, перегляньте розділ про [Бенчмарки](benchmarks.md){.internal-link target=_blank}.

448
docs/uk/docs/python-types.md

@ -0,0 +1,448 @@
# Вступ до типів Python
Python підтримує додаткові "підказки типу" ("type hints") (також звані "анотаціями типу" ("type annotations")).
Ці **"type hints"** є спеціальним синтаксисом, що дозволяє оголошувати <abbr title="наприклад: str, int, float, bool">тип</abbr> змінної.
За допомогою оголошення типів для ваших змінних, редактори та інструменти можуть надати вам кращу підтримку.
Це просто **швидкий посібник / нагадування** про анотації типів у Python. Він покриває лише мінімум, необхідний щоб використовувати їх з **FastAPI**... що насправді дуже мало.
**FastAPI** повністю базується на цих анотаціях типів, вони дають йому багато переваг.
Але навіть якщо ви ніколи не використаєте **FastAPI**, вам буде корисно дізнатись трохи про них.
!!! note
Якщо ви експерт у Python і ви вже знаєте усе про анотації типів - перейдіть до наступного розділу.
## Мотивація
Давайте почнемо з простого прикладу:
```Python
{!../../../docs_src/python_types/tutorial001.py!}
```
Виклик цієї програми виводить:
```
John Doe
```
Функція виконує наступне:
* Бере `first_name` та `last_name`.
* Конвертує кожну літеру кожного слова у верхній регістр за допомогою `title()`.
* <abbr title="З’єднує їх, як одне ціле. З вмістом один за одним.">Конкатенує</abbr> їх разом із пробілом по середині.
```Python hl_lines="2"
{!../../../docs_src/python_types/tutorial001.py!}
```
### Редагуйте це
Це дуже проста програма.
Але тепер уявіть, що ви писали це з нуля.
У певний момент ви розпочали б визначення функції, у вас були б готові параметри...
Але тоді вам потрібно викликати "той метод, який переводить першу літеру у верхній регістр".
Це буде `upper`? Чи `uppercase`? `first_uppercase`? `capitalize`?
Тоді ви спробуєте давнього друга програміста - автозаповнення редактора коду.
Ви надрукуєте перший параметр функції, `first_name`, тоді крапку (`.`), а тоді натиснете `Ctrl+Space`, щоб запустити автозаповнення.
Але, на жаль, ви не отримаєте нічого корисного:
<img src="/img/python-types/image01.png">
### Додайте типи
Давайте змінимо один рядок з попередньої версії.
Ми змінимо саме цей фрагмент, параметри функції, з:
```Python
first_name, last_name
```
на:
```Python
first_name: str, last_name: str
```
Ось і все.
Це "type hints":
```Python hl_lines="1"
{!../../../docs_src/python_types/tutorial002.py!}
```
Це не те саме, що оголошення значень за замовчуванням, як це було б з:
```Python
first_name="john", last_name="doe"
```
Це зовсім інше.
Ми використовуємо двокрапку (`:`), не дорівнює (`=`).
І додавання анотації типу зазвичай не змінює того, що сталось би без них.
Але тепер, уявіть що ви посеред процесу створення функції, але з анотаціями типів.
В цей же момент, ви спробуєте викликати автозаповнення з допомогою `Ctrl+Space` і побачите:
<img src="/img/python-types/image02.png">
Разом з цим, ви можете прокручувати, переглядати опції, допоки ви не знайдете одну, що звучить схоже:
<img src="/img/python-types/image03.png">
## Більше мотивації
Перевірте цю функцію, вона вже має анотацію типу:
```Python hl_lines="1"
{!../../../docs_src/python_types/tutorial003.py!}
```
Оскільки редактор знає типи змінних, ви не тільки отримаєте автозаповнення, ви також отримаєте перевірку помилок:
<img src="/img/python-types/image04.png">
Тепер ви знаєте, щоб виправити це, вам потрібно перетворити `age` у строку з допомогою `str(age)`:
```Python hl_lines="2"
{!../../../docs_src/python_types/tutorial004.py!}
```
## Оголошення типів
Щойно ви побачили основне місце для оголошення анотацій типу. Як параметри функції.
Це також основне місце, де ви б їх використовували у **FastAPI**.
### Прості типи
Ви можете оголошувати усі стандартні типи у Python, не тільки `str`.
Ви можете використовувати, наприклад:
* `int`
* `float`
* `bool`
* `bytes`
```Python hl_lines="1"
{!../../../docs_src/python_types/tutorial005.py!}
```
### Generic-типи з параметрами типів
Існують деякі структури даних, які можуть містити інші значення, наприклад `dict`, `list`, `set` та `tuple`. І внутрішні значення також можуть мати свій тип.
Ці типи, які мають внутрішні типи, називаються "**generic**" типами. І оголосити їх можна навіть із внутрішніми типами.
Щоб оголосити ці типи та внутрішні типи, ви можете використовувати стандартний модуль Python `typing`. Він існує спеціально для підтримки анотацій типів.
#### Новіші версії Python
Синтаксис із використанням `typing` **сумісний** з усіма версіями, від Python 3.6 до останніх, включаючи Python 3.9, Python 3.10 тощо.
У міру розвитку Python **новіші версії** мають покращену підтримку анотацій типів і в багатьох випадках вам навіть не потрібно буде імпортувати та використовувати модуль `typing` для оголошення анотацій типу.
Якщо ви можете вибрати новішу версію Python для свого проекту, ви зможете скористатися цією додатковою простотою. Дивіться кілька прикладів нижче.
#### List (список)
Наприклад, давайте визначимо змінну, яка буде `list` із `str`.
=== "Python 3.6 і вище"
З модуля `typing`, імпортуємо `List` (з великої літери `L`):
``` Python hl_lines="1"
{!> ../../../docs_src/python_types/tutorial006.py!}
```
Оголосимо змінну з тим самим синтаксисом двокрапки (`:`).
Як тип вкажемо `List`, який ви імпортували з `typing`.
Оскільки список є типом, який містить деякі внутрішні типи, ви поміщаєте їх у квадратні дужки:
```Python hl_lines="4"
{!> ../../../docs_src/python_types/tutorial006.py!}
```
=== "Python 3.9 і вище"
Оголосимо змінну з тим самим синтаксисом двокрапки (`:`).
Як тип вкажемо `list`.
Оскільки список є типом, який містить деякі внутрішні типи, ви поміщаєте їх у квадратні дужки:
```Python hl_lines="1"
{!> ../../../docs_src/python_types/tutorial006_py39.py!}
```
!!! info
Ці внутрішні типи в квадратних дужках називаються "параметрами типу".
У цьому випадку, `str` це параметр типу переданий у `List` (або `list` у Python 3.9 і вище).
Це означає: "змінна `items` це `list`, і кожен з елементів у цьому списку - `str`".
!!! tip
Якщо ви використовуєте Python 3.9 і вище, вам не потрібно імпортувати `List` з `typing`, ви можете використовувати натомість тип `list`.
Зробивши це, ваш редактор може надати підтримку навіть під час обробки елементів зі списку:
<img src="/img/python-types/image05.png">
Без типів цього майже неможливо досягти.
Зверніть увагу, що змінна `item` є одним із елементів у списку `items`.
І все ж редактор знає, що це `str`, і надає підтримку для цього.
#### Tuple and Set (кортеж та набір)
Ви повинні зробити те ж саме, щоб оголосити `tuple` і `set`:
=== "Python 3.6 і вище"
```Python hl_lines="1 4"
{!> ../../../docs_src/python_types/tutorial007.py!}
```
=== "Python 3.9 і вище"
```Python hl_lines="1"
{!> ../../../docs_src/python_types/tutorial007_py39.py!}
```
Це означає:
* Змінна `items_t` це `tuple` з 3 елементами, `int`, ще `int`, та `str`.
* Змінна `items_s` це `set`, і кожен його елемент типу `bytes`.
#### Dict (словник)
Щоб оголосити `dict`, вам потрібно передати 2 параметри типу, розділені комами.
Перший параметр типу для ключа у `dict`.
Другий параметр типу для значення у `dict`:
=== "Python 3.6 і вище"
```Python hl_lines="1 4"
{!> ../../../docs_src/python_types/tutorial008.py!}
```
=== "Python 3.9 і вище"
```Python hl_lines="1"
{!> ../../../docs_src/python_types/tutorial008_py39.py!}
```
Це означає:
* Змінна `prices` це `dict`:
* Ключі цього `dict` типу `str` (наприклад, назва кожного елементу).
* Значення цього `dict` типу `float` (наприклад, ціна кожного елементу).
#### Union (об'єднання)
Ви можете оголосити, що змінна може бути будь-яким із **кількох типів**, наприклад, `int` або `str`.
У Python 3.6 і вище (включаючи Python 3.10) ви можете використовувати тип `Union` з `typing` і вставляти в квадратні дужки можливі типи, які можна прийняти.
У Python 3.10 також є **альтернативний синтаксис**, у якому ви можете розділити можливі типи за допомогою <abbr title='також називають «побітовим "або" оператором», але це значення тут не актуальне'>вертикальної смуги (`|`)</abbr>.
=== "Python 3.6 і вище"
```Python hl_lines="1 4"
{!> ../../../docs_src/python_types/tutorial008b.py!}
```
=== "Python 3.10 і вище"
```Python hl_lines="1"
{!> ../../../docs_src/python_types/tutorial008b_py310.py!}
```
В обох випадках це означає, що `item` може бути `int` або `str`.
#### Possibly `None` (Optional)
Ви можете оголосити, що значення може мати тип, наприклад `str`, але також може бути `None`.
У Python 3.6 і вище (включаючи Python 3.10) ви можете оголосити його, імпортувавши та використовуючи `Optional` з модуля `typing`.
```Python hl_lines="1 4"
{!../../../docs_src/python_types/tutorial009.py!}
```
Використання `Optional[str]` замість просто `str` дозволить редактору допомогти вам виявити помилки, коли ви могли б вважати, що значенням завжди є `str`, хоча насправді воно також може бути `None`.
`Optional[Something]` насправді є скороченням для `Union[Something, None]`, вони еквівалентні.
Це також означає, що в Python 3.10 ви можете використовувати `Something | None`:
=== "Python 3.6 і вище"
```Python hl_lines="1 4"
{!> ../../../docs_src/python_types/tutorial009.py!}
```
=== "Python 3.6 і вище - альтернатива"
```Python hl_lines="1 4"
{!> ../../../docs_src/python_types/tutorial009b.py!}
```
=== "Python 3.10 і вище"
```Python hl_lines="1"
{!> ../../../docs_src/python_types/tutorial009_py310.py!}
```
#### Generic типи
Ці типи, які приймають параметри типу у квадратних дужках, називаються **Generic types** or **Generics**, наприклад:
=== "Python 3.6 і вище"
* `List`
* `Tuple`
* `Set`
* `Dict`
* `Union`
* `Optional`
* ...та інші.
=== "Python 3.9 і вище"
Ви можете використовувати ті самі вбудовані типи, як generic (з квадратними дужками та типами всередині):
* `list`
* `tuple`
* `set`
* `dict`
І те саме, що й у Python 3.6, із модуля `typing`:
* `Union`
* `Optional`
* ...та інші.
=== "Python 3.10 і вище"
Ви можете використовувати ті самі вбудовані типи, як generic (з квадратними дужками та типами всередині):
* `list`
* `tuple`
* `set`
* `dict`
І те саме, що й у Python 3.6, із модуля `typing`:
* `Union`
* `Optional` (так само як у Python 3.6)
* ...та інші.
У Python 3.10, як альтернатива використанню `Union` та `Optional`, ви можете використовувати <abbr title='також називають «побітовим "або" оператором», але це значення тут не актуальне'>вертикальну смугу (`|`)</abbr> щоб оголосити об'єднання типів.
### Класи як типи
Ви також можете оголосити клас як тип змінної.
Скажімо, у вас є клас `Person` з імʼям:
```Python hl_lines="1-3"
{!../../../docs_src/python_types/tutorial010.py!}
```
Потім ви можете оголосити змінну типу `Person`:
```Python hl_lines="6"
{!../../../docs_src/python_types/tutorial010.py!}
```
І знову ж таки, ви отримуєте всю підтримку редактора:
<img src="/img/python-types/image06.png">
## Pydantic моделі
<a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> це бібліотека Python для валідації даних.
Ви оголошуєте «форму» даних як класи з атрибутами.
І кожен атрибут має тип.
Потім ви створюєте екземпляр цього класу з деякими значеннями, і він перевірить ці значення, перетворить їх у відповідний тип (якщо є потреба) і надасть вам об’єкт з усіма даними.
І ви отримуєте всю підтримку редактора з цим отриманим об’єктом.
Приклад з документації Pydantic:
=== "Python 3.6 і вище"
```Python
{!> ../../../docs_src/python_types/tutorial011.py!}
```
=== "Python 3.9 і вище"
```Python
{!> ../../../docs_src/python_types/tutorial011_py39.py!}
```
=== "Python 3.10 і вище"
```Python
{!> ../../../docs_src/python_types/tutorial011_py310.py!}
```
!!! info
Щоб дізнатись більше про <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic, перегляньте його документацію</a>.
**FastAPI** повністю базується на Pydantic.
Ви побачите набагато більше цього всього на практиці в [Tutorial - User Guide](tutorial/index.md){.internal-link target=_blank}.
## Анотації типів у **FastAPI**
**FastAPI** використовує ці підказки для виконання кількох речей.
З **FastAPI** ви оголошуєте параметри з підказками типу, і отримуєте:
* **Підтримку редактора**.
* **Перевірку типів**.
...і **FastAPI** використовує ті самі оголошення для:
* **Визначення вимог**: з параметрів шляху запиту, параметрів запиту, заголовків, тіл, залежностей тощо.
* **Перетворення даних**: із запиту в необхідний тип.
* **Перевірка даних**: що надходять від кожного запиту:
* Генерування **автоматичних помилок**, що повертаються клієнту, коли дані недійсні.
* **Документування** API за допомогою OpenAPI:
* який потім використовується для автоматичної інтерактивної документації користувальницьких інтерфейсів.
Все це може здатися абстрактним. Не хвилюйтеся. Ви побачите все це в дії в [Туторіал - Посібник користувача](tutorial/index.md){.internal-link target=_blank}.
Важливо те, що за допомогою стандартних типів Python в одному місці (замість того, щоб додавати більше класів, декораторів тощо), **FastAPI** зробить багато роботи за вас.
!!! info
Якщо ви вже пройшли весь навчальний посібник і повернулися, щоб дізнатися більше про типи, ось хороший ресурс <a href="https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html" class="external-link" target="_blank">"шпаргалка" від `mypy`</a>.

80
docs/uk/docs/tutorial/index.md

@ -0,0 +1,80 @@
# Туторіал - Посібник користувача
У цьому посібнику показано, як користуватися **FastAPI** з більшістю його функцій, крок за кроком.
Кожен розділ поступово надбудовується на попередні, але він структурований на окремі теми, щоб ви могли перейти безпосередньо до будь-якої конкретної, щоб вирішити ваші конкретні потреби API.
Він також створений як довідник для роботи у майбутньому.
Тож ви можете повернутися і побачити саме те, що вам потрібно.
## Запустіть код
Усі блоки коду можна скопіювати та використовувати безпосередньо (це фактично перевірені файли Python).
Щоб запустити будь-який із прикладів, скопіюйте код у файл `main.py` і запустіть `uvicorn` за допомогою:
<div class="termy">
```console
$ uvicorn main:app --reload
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
<span style="color: green;">INFO</span>: Started reloader process [28720]
<span style="color: green;">INFO</span>: Started server process [28722]
<span style="color: green;">INFO</span>: Waiting for application startup.
<span style="color: green;">INFO</span>: Application startup complete.
```
</div>
**ДУЖЕ радимо** написати або скопіювати код, відредагувати його та запустити локально.
Використання його у своєму редакторі – це те, що дійсно показує вам переваги FastAPI, бачите, як мало коду вам потрібно написати, всі перевірки типів, автозаповнення тощо.
---
## Встановлення FastAPI
Першим кроком є встановлення FastAPI.
Для туторіалу ви можете встановити його з усіма необов’язковими залежностями та функціями:
<div class="termy">
```console
$ pip install "fastapi[all]"
---> 100%
```
</div>
...який також включає `uvicorn`, який ви можете використовувати як сервер, який запускає ваш код.
!!! note
Ви також можете встановити його частина за частиною.
Це те, що ви, ймовірно, зробили б, коли захочете розгорнути свою програму у виробничому середовищі:
```
pip install fastapi
```
Також встановіть `uvicorn`, щоб він працював як сервер:
```
pip install "uvicorn[standard]"
```
І те саме для кожної з опціональних залежностей, які ви хочете використовувати.
## Розширений посібник користувача
Існує також **Розширений посібник користувача**, який ви зможете прочитати пізніше після цього **Туторіал - Посібник користувача**.
**Розширений посібник користувача** засновано на цьому, використовує ті самі концепції та навчає вас деяким додатковим функціям.
Але вам слід спочатку прочитати **Туторіал - Посібник користувача** (те, що ви зараз читаєте).
Він розроблений таким чином, що ви можете створити повну програму лише за допомогою **Туторіал - Посібник користувача**, а потім розширити її різними способами, залежно від ваших потреб, використовуючи деякі з додаткових ідей з **Розширеного посібника користувача** .

333
docs/vi/docs/tutorial/first-steps.md

@ -0,0 +1,333 @@
# Những bước đầu tiên
Tệp tin FastAPI đơn giản nhất có thể trông như này:
```Python
{!../../../docs_src/first_steps/tutorial001.py!}
```
Sao chép sang một tệp tin `main.py`.
Chạy live server:
<div class="termy">
```console
$ uvicorn main:app --reload
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
<span style="color: green;">INFO</span>: Started reloader process [28720]
<span style="color: green;">INFO</span>: Started server process [28722]
<span style="color: green;">INFO</span>: Waiting for application startup.
<span style="color: green;">INFO</span>: Application startup complete.
```
</div>
!!! note
Câu lệnh `uvicorn main:app` được giải thích như sau:
* `main`: tệp tin `main.py` (một Python "mô đun").
* `app`: một object được tạo ra bên trong `main.py` với dòng `app = FastAPI()`.
* `--reload`: làm server khởi động lại sau mỗi lần thay đổi. Chỉ sử dụng trong môi trường phát triển.
Trong output, có một dòng giống như:
```hl_lines="4"
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
Dòng đó cho thấy URL, nơi mà app của bạn đang được chạy, trong máy local của bạn.
### Kiểm tra
Mở trình duyệt của bạn tại <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>.
Bạn sẽ thấy một JSON response như:
```JSON
{"message": "Hello World"}
```
### Tài liệu tương tác API
Bây giờ tới <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
Bạn sẽ thấy một tài liệu tương tác API (cung cấp bởi <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
### Phiên bản thay thế của tài liệu API
Và bây giờ tới <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
Bạn sẽ thấy một bản thay thế của tài liệu (cung cấp bởi <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>):
![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
### OpenAPI
**FastAPI** sinh một "schema" với tất cả API của bạn sử dụng tiêu chuẩn **OpenAPI** cho định nghĩa các API.
#### "Schema"
Một "schema" là một định nghĩa hoặc mô tả thứ gì đó. Không phải code triển khai của nó, nhưng chỉ là một bản mô tả trừu tượng.
#### API "schema"
Trong trường hợp này, <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> là một bản mô tả bắt buộc cơ chế định nghĩa API của bạn.
Định nghĩa cấu trúc này bao gồm những đường dẫn API của bạn, các tham số có thể có,...
#### "Cấu trúc" dữ liệu
Thuật ngữ "cấu trúc" (schema) cũng có thể được coi như là hình dạng của dữ liệu, tương tự như một JSON content.
Trong trường hợp đó, nó có nghĩa là các thuộc tính JSON và các kiểu dữ liệu họ có,...
#### OpenAPI và JSON Schema
OpenAPI định nghĩa một cấu trúc API cho API của bạn. Và cấu trúc đó bao gồm các dịnh nghĩa (or "schema") về dữ liệu được gửi đi và nhận về bởi API của bạn, sử dụng **JSON Schema**, một tiêu chuẩn cho cấu trúc dữ liệu JSON.
#### Kiểm tra `openapi.json`
Nếu bạn tò mò về việc cấu trúc OpenAPI nhìn như thế nào thì FastAPI tự động sinh một JSON (schema) với các mô tả cho tất cả API của bạn.
Bạn có thể thấy nó trực tiếp tại: <a href="http://127.0.0.1:8000/openapi.json" class="external-link" target="_blank">http://127.0.0.1:8000/openapi.json</a>.
Nó sẽ cho thấy một JSON bắt đầu giống như:
```JSON
{
"openapi": "3.1.0",
"info": {
"title": "FastAPI",
"version": "0.1.0"
},
"paths": {
"/items/": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
...
```
#### OpenAPI dùng để làm gì?
Cấu trúc OpenAPI là sức mạnh của tài liệu tương tác.
Và có hàng tá các bản thay thế, tất cả đều dựa trên OpenAPI. Bạn có thể dễ dàng thêm bất kì bản thay thế bào cho ứng dụng của bạn được xây dựng với **FastAPI**.
Bạn cũng có thể sử dụng nó để sinh code tự động, với các client giao viết qua API của bạn. Ví dụ, frontend, mobile hoặc các ứng dụng IoT.
## Tóm lại, từng bước một
### Bước 1: import `FastAPI`
```Python hl_lines="1"
{!../../../docs_src/first_steps/tutorial001.py!}
```
`FastAPI` là một Python class cung cấp tất cả chức năng cho API của bạn.
!!! note "Chi tiết kĩ thuật"
`FastAPI` là một class kế thừa trực tiếp `Starlette`.
Bạn cũng có thể sử dụng tất cả <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> chức năng với `FastAPI`.
### Bước 2: Tạo một `FastAPI` "instance"
```Python hl_lines="3"
{!../../../docs_src/first_steps/tutorial001.py!}
```
Biến `app` này là một "instance" của class `FastAPI`.
Đây sẽ là điểm cốt lõi để tạo ra tất cả API của bạn.
`app` này chính là điều được nhắc tới bởi `uvicorn` trong câu lệnh:
<div class="termy">
```console
$ uvicorn main:app --reload
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
Nếu bạn tạo ứng dụng của bạn giống như:
```Python hl_lines="3"
{!../../../docs_src/first_steps/tutorial002.py!}
```
Và đặt nó trong một tệp tin `main.py`, sau đó bạn sẽ gọi `uvicorn` giống như:
<div class="termy">
```console
$ uvicorn main:my_awesome_api --reload
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
### Bước 3: tạo một *đường dẫn toán tử*
#### Đường dẫn
"Đường dẫn" ở đây được nhắc tới là phần cuối cùng của URL bắt đầu từ `/`.
Do đó, trong một URL nhìn giống như:
```
https://example.com/items/foo
```
...đường dẫn sẽ là:
```
/items/foo
```
!!! info
Một đường dẫn cũng là một cách gọi chung cho một "endpoint" hoặc một "route".
Trong khi xây dựng một API, "đường dẫn" là các chính để phân tách "mối quan hệ" và "tài nguyên".
#### Toán tử (Operation)
"Toán tử" ở đây được nhắc tới là một trong các "phương thức" HTTP.
Một trong những:
* `POST`
* `GET`
* `PUT`
* `DELETE`
...và một trong những cái còn lại:
* `OPTIONS`
* `HEAD`
* `PATCH`
* `TRACE`
Trong giao thức HTTP, bạn có thể giao tiếp trong mỗi đường dẫn sử dụng một (hoặc nhiều) trong các "phương thức này".
---
Khi xây dựng các API, bạn thường sử dụng cụ thể các phương thức HTTP này để thực hiện một hành động cụ thể.
Thông thường, bạn sử dụng
* `POST`: để tạo dữ liệu.
* `GET`: để đọc dữ liệu.
* `PUT`: để cập nhật dữ liệu.
* `DELETE`: để xóa dữ liệu.
Do đó, trong OpenAPI, mỗi phương thức HTTP được gọi là một "toán tử (operation)".
Chúng ta cũng sẽ gọi chúng là "**các toán tử**".
#### Định nghĩa moojt *decorator cho đường dẫn toán tử*
```Python hl_lines="6"
{!../../../docs_src/first_steps/tutorial001.py!}
```
`@app.get("/")` nói **FastAPI** rằng hàm bên dưới có trách nhiệm xử lí request tới:
* đường dẫn `/`
* sử dụng một <abbr title="an HTTP GET method">toán tử<code>get</code></abbr>
!!! info Thông tin về "`@decorator`"
Cú pháp `@something` trong Python được gọi là một "decorator".
Bạn đặt nó trên một hàm. Giống như một chiếc mũ xinh xắn (Tôi ddonas đó là lí do mà thuật ngữ này ra đời).
Một "decorator" lấy một hàm bên dưới và thực hiện một vài thứ với nó.
Trong trường hợp của chúng ta, decorator này nói **FastAPI** rằng hàm bên dưới ứng với **đường dẫn** `/` và một **toán tử** `get`.
Nó là một "**decorator đường dẫn toán tử**".
Bạn cũng có thể sử dụng với các toán tử khác:
* `@app.post()`
* `@app.put()`
* `@app.delete()`
Và nhiều hơn với các toán tử còn lại:
* `@app.options()`
* `@app.head()`
* `@app.patch()`
* `@app.trace()`
!!! tip
Bạn thoải mái sử dụng mỗi toán tử (phương thức HTTP) như bạn mơ ước.
**FastAPI** không bắt buộc bất kì ý nghĩa cụ thể nào.
Thông tin ở đây được biểu thị như là một chỉ dẫn, không phải là một yêu cầu bắt buộc.
Ví dụ, khi sử dụng GraphQL bạn thông thường thực hiện tất cả các hành động chỉ bằng việc sử dụng các toán tử `POST`.
### Step 4: Định nghĩa **hàm cho đường dẫn toán tử**
Đây là "**hàm cho đường dẫn toán tử**":
* **đường dẫn**: là `/`.
* **toán tử**: là `get`.
* **hàm**: là hàm bên dưới "decorator" (bên dưới `@app.get("/")`).
```Python hl_lines="7"
{!../../../docs_src/first_steps/tutorial001.py!}
```
Đây là một hàm Python.
Nó sẽ được gọi bởi **FastAPI** bất cứ khi nào nó nhận một request tới URL "`/`" sử dụng một toán tử `GET`.
Trong trường hợp này, nó là một hàm `async`.
---
Bạn cũng có thể định nghĩa nó như là một hàm thông thường thay cho `async def`:
```Python hl_lines="7"
{!../../../docs_src/first_steps/tutorial003.py!}
```
!!! note
Nếu bạn không biết sự khác nhau, kiểm tra [Async: *"Trong khi vội vàng?"*](../async.md#in-a-hurry){.internal-link target=_blank}.
### Bước 5: Nội dung trả về
```Python hl_lines="8"
{!../../../docs_src/first_steps/tutorial001.py!}
```
Bạn có thể trả về một `dict`, `list`, một trong những giá trị đơn như `str`, `int`,...
Bạn cũng có thể trả về Pydantic model (bạn sẽ thấy nhiều hơn về nó sau).
Có nhiều object và model khác nhau sẽ được tự động chuyển đổi sang JSON (bao gồm cả ORM,...). Thử sử dụng loại ưa thích của bạn, nó có khả năng cao đã được hỗ trợ.
## Tóm lại
* Import `FastAPI`.
* Tạo một `app` instance.
* Viết một **decorator cho đường dẫn toán tử** (giống như `@app.get("/")`).
* Viết một **hàm cho đường dẫn toán tử** (giống như `def root(): ...` ở trên).
* Chạy server trong môi trường phát triển (giống như `uvicorn main:app --reload`).

80
docs/vi/docs/tutorial/index.md

@ -0,0 +1,80 @@
# Hướng dẫn sử dụng
Hướng dẫn này cho bạn thấy từng bước cách sử dụng **FastAPI** đa số các tính năng của nó.
Mỗi phần được xây dựng từ những phần trước đó, nhưng nó được cấu trúc thành các chủ đề riêng biệt, do đó bạn có thể xem trực tiếp từng phần cụ thể bất kì để giải quyết những API cụ thể mà bạn cần.
Nó cũng được xây dựng để làm việc như một tham chiếu trong tương lai.
Do đó bạn có thể quay lại và tìm chính xác những gì bạn cần.
## Chạy mã
Tất cả các code block có thể được sao chép và sử dụng trực tiếp (chúng thực chất là các tệp tin Python đã được kiểm thử).
Để chạy bất kì ví dụ nào, sao chép code tới tệp tin `main.py`, và bắt đầu `uvicorn` với:
<div class="termy">
```console
$ uvicorn main:app --reload
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
<span style="color: green;">INFO</span>: Started reloader process [28720]
<span style="color: green;">INFO</span>: Started server process [28722]
<span style="color: green;">INFO</span>: Waiting for application startup.
<span style="color: green;">INFO</span>: Application startup complete.
```
</div>
**Khuyến khích** bạn viết hoặc sao chép code, sửa và chạy nó ở local.
Sử dụng nó trong trình soạn thảo của bạn thực sự cho bạn thấy những lợi ích của FastAPI, thấy được cách bạn viết code ít hơn, tất cả đều được type check, autocompletion,...
---
## Cài đặt FastAPI
Bước đầu tiên là cài đặt FastAPI.
Với hướng dẫn này, bạn có thể muốn cài đặt nó với tất cả các phụ thuộc và tính năng tùy chọn:
<div class="termy">
```console
$ pip install "fastapi[all]"
---> 100%
```
</div>
...dó cũng bao gồm `uvicorn`, bạn có thể sử dụng như một server để chạy code của bạn.
!!! note
Bạn cũng có thể cài đặt nó từng phần.
Đây là những gì bạn có thể sẽ làm một lần duy nhất bạn muốn triển khai ứng dụng của bạn lên production:
```
pip install fastapi
```
Cũng cài đặt `uvicorn` để làm việc như một server:
```
pip install "uvicorn[standard]"
```
Và tương tự với từng phụ thuộc tùy chọn mà bạn muốn sử dụng.
## Hướng dẫn nâng cao
Cũng có một **Hướng dẫn nâng cao** mà bạn có thể đọc nó sau **Hướng dẫn sử dụng**.
**Hướng dẫn sử dụng nâng cao**, xây dựng dựa trên cái này, sử dụng các khái niệm tương tự, và dạy bạn những tính năng mở rộng.
Nhưng bạn nên đọc **Hướng dẫn sử dụng** đầu tiên (những gì bạn đang đọc).
Nó được thiết kế do đó bạn có thể xây dựng một ứng dụng hoàn chỉnh chỉ với **Hướng dẫn sử dụng**, và sau đó mở rộng nó theo các cách khác nhau, phụ thuộc vào những gì bạn cần, sử dụng một vài ý tưởng bổ sung từ **Hướng dẫn sử dụng nâng cao**.

266
docs/zh/docs/advanced/generate-clients.md

@ -0,0 +1,266 @@
# 生成客户端
因为 **FastAPI** 是基于OpenAPI规范的,自然您可以使用许多相匹配的工具,包括自动生成API文档 (由 Swagger UI 提供)。
一个不太明显而又特别的优势是,你可以为你的API针对不同的**编程语言**来**生成客户端**(有时候被叫做 <abbr title="Software Development Kits">**SDKs**</abbr> )。
## OpenAPI 客户端生成
有许多工具可以从**OpenAPI**生成客户端。
一个常见的工具是 <a href="https://openapi-generator.tech/" class="external-link" target="_blank">OpenAPI Generator</a>
如果您正在开发**前端**,一个非常有趣的替代方案是 <a href="https://github.com/ferdikoomen/openapi-typescript-codegen" class="external-link" target="_blank">openapi-typescript-codegen</a>
## 生成一个 TypeScript 前端客户端
让我们从一个简单的 FastAPI 应用开始:
=== "Python 3.9+"
```Python hl_lines="7-9 12-13 16-17 21"
{!> ../../../docs_src/generate_clients/tutorial001_py39.py!}
```
=== "Python 3.6+"
```Python hl_lines="9-11 14-15 18 19 23"
{!> ../../../docs_src/generate_clients/tutorial001.py!}
```
请注意,*路径操作* 定义了他们所用于请求数据和回应数据的模型,所使用的模型是`Item` 和 `ResponseMessage`
### API 文档
如果您访问API文档,您将看到它具有在请求中发送和在响应中接收数据的**模式(schemas)**:
<img src="/img/tutorial/generate-clients/image01.png">
您可以看到这些模式,因为它们是用程序中的模型声明的。
那些信息可以在应用的 **OpenAPI模式** 被找到,然后显示在API文档中(通过Swagger UI)。
OpenAPI中所包含的模型里有相同的信息可以用于 **生成客户端代码**
### 生成一个TypeScript 客户端
现在我们有了带有模型的应用,我们可以为前端生成客户端代码。
#### 安装 `openapi-typescript-codegen`
您可以使用以下工具在前端代码中安装 `openapi-typescript-codegen`:
<div class="termy">
```console
$ npm install openapi-typescript-codegen --save-dev
---> 100%
```
</div>
#### 生成客户端代码
要生成客户端代码,您可以使用现在将要安装的命令行应用程序 `openapi`
因为它安装在本地项目中,所以您可能无法直接使用此命令,但您可以将其放在 `package.json` 文件中。
它可能看起来是这样的:
```JSON hl_lines="7"
{
"name": "frontend-app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"generate-client": "openapi --input http://localhost:8000/openapi.json --output ./src/client --client axios"
},
"author": "",
"license": "",
"devDependencies": {
"openapi-typescript-codegen": "^0.20.1",
"typescript": "^4.6.2"
}
}
```
在这里添加 NPM `generate-client` 脚本后,您可以使用以下命令运行它:
<div class="termy">
```console
$ npm run generate-client
[email protected] generate-client /home/user/code/frontend-app
> openapi --input http://localhost:8000/openapi.json --output ./src/client --client axios
```
</div>
此命令将在 `./src/client` 中生成代码,并将在其内部使用 `axios`(前端HTTP库)。
### 尝试客户端代码
现在您可以导入并使用客户端代码,它可能看起来像这样,请注意,您可以为这些方法使用自动补全:
<img src="/img/tutorial/generate-clients/image02.png">
您还将自动补全要发送的数据:
<img src="/img/tutorial/generate-clients/image03.png">
!!! tip
请注意, `name``price` 的自动补全,是通过其在`Item`模型(FastAPI)中的定义实现的。
如果发送的数据字段不符,你也会看到编辑器的错误提示:
<img src="/img/tutorial/generate-clients/image04.png">
响应(response)对象也拥有自动补全:
<img src="/img/tutorial/generate-clients/image05.png">
## 带有标签的 FastAPI 应用
在许多情况下,你的FastAPI应用程序会更复杂,你可能会使用标签来分隔不同组的*路径操作(path operations)*。
例如,您可以有一个用 `items` 的部分和另一个用于 `users` 的部分,它们可以用标签来分隔:
=== "Python 3.9+"
```Python hl_lines="21 26 34"
{!> ../../../docs_src/generate_clients/tutorial002_py39.py!}
```
=== "Python 3.6+"
```Python hl_lines="23 28 36"
{!> ../../../docs_src/generate_clients/tutorial002.py!}
```
### 生成带有标签的 TypeScript 客户端
如果您使用标签为FastAPI应用生成客户端,它通常也会根据标签分割客户端代码。
通过这种方式,您将能够为客户端代码进行正确地排序和分组:
<img src="/img/tutorial/generate-clients/image06.png">
在这个案例中,您有:
* `ItemsService`
* `UsersService`
### 客户端方法名称
现在生成的方法名像 `createItemItemsPost` 看起来不太简洁:
```TypeScript
ItemsService.createItemItemsPost({name: "Plumbus", price: 5})
```
...这是因为客户端生成器为每个 *路径操作* 使用OpenAPI的内部 **操作 ID(operation ID)**
OpenAPI要求每个操作 ID 在所有 *路径操作* 中都是唯一的,因此 FastAPI 使用**函数名**、**路径**和**HTTP方法/操作**来生成此操作ID,因为这样可以确保这些操作 ID 是唯一的。
但接下来我会告诉你如何改进。 🤓
## 自定义操作ID和更好的方法名
您可以**修改**这些操作ID的**生成**方式,以使其更简洁,并在客户端中具有**更简洁的方法名称**。
在这种情况下,您必须确保每个操作ID在其他方面是**唯一**的。
例如,您可以确保每个*路径操作*都有一个标签,然后根据**标签**和*路径操作***名称**(函数名)来生成操作ID。
### 自定义生成唯一ID函数
FastAPI为每个*路径操作*使用一个**唯一ID**,它用于**操作ID**,也用于任何所需自定义模型的名称,用于请求或响应。
你可以自定义该函数。它接受一个 `APIRoute` 对象作为输入,并输出一个字符串。
例如,以下是一个示例,它使用第一个标签(你可能只有一个标签)和*路径操作*名称(函数名)。
然后,你可以将这个自定义函数作为 `generate_unique_id_function` 参数传递给 **FastAPI**:
=== "Python 3.9+"
```Python hl_lines="6-7 10"
{!> ../../../docs_src/generate_clients/tutorial003_py39.py!}
```
=== "Python 3.6+"
```Python hl_lines="8-9 12"
{!> ../../../docs_src/generate_clients/tutorial003.py!}
```
### 使用自定义操作ID生成TypeScript客户端
现在,如果你再次生成客户端,你会发现它具有改善的方法名称:
<img src="/img/tutorial/generate-clients/image07.png">
正如你所见,现在方法名称中只包含标签和函数名,不再包含URL路径和HTTP操作的信息。
### 预处理用于客户端生成器的OpenAPI规范
生成的代码仍然存在一些**重复的信息**。
我们已经知道该方法与 **items** 相关,因为它在 `ItemsService` 中(从标签中获取),但方法名中仍然有标签名作为前缀。😕
一般情况下对于OpenAPI,我们可能仍然希望保留它,因为这将确保操作ID是**唯一的**。
但对于生成的客户端,我们可以在生成客户端之前**修改** OpenAPI 操作ID,以使方法名称更加美观和**简洁**。
我们可以将 OpenAPI JSON 下载到一个名为`openapi.json`的文件中,然后使用以下脚本**删除此前缀的标签**:
```Python
{!../../../docs_src/generate_clients/tutorial004.py!}
```
通过这样做,操作ID将从类似于 `items-get_items` 的名称重命名为 `get_items` ,这样客户端生成器就可以生成更简洁的方法名称。
### 使用预处理的OpenAPI生成TypeScript客户端
现在,由于最终结果保存在文件openapi.json中,你可以修改 package.json 文件以使用此本地文件,例如:
```JSON hl_lines="7"
{
"name": "frontend-app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"generate-client": "openapi --input ./openapi.json --output ./src/client --client axios"
},
"author": "",
"license": "",
"devDependencies": {
"openapi-typescript-codegen": "^0.20.1",
"typescript": "^4.6.2"
}
}
```
生成新的客户端之后,你现在将拥有**清晰的方法名称**,具备**自动补全**、**错误提示**等功能:
<img src="/img/tutorial/generate-clients/image08.png">
## 优点
当使用自动生成的客户端时,你将获得以下的自动补全功能:
* 方法。
* 请求体中的数据、查询参数等。
* 响应数据。
你还将获得针对所有内容的错误提示。
每当你更新后端代码并**重新生成**前端代码时,新的*路径操作*将作为方法可用,旧的方法将被删除,并且其他任何更改将反映在生成的代码中。 🤓
这也意味着如果有任何更改,它将自动**反映**在客户端代码中。如果你**构建**客户端,在使用的数据上存在**不匹配**时,它将报错。
因此,你将在开发周期的早期**检测到许多错误**,而不必等待错误在生产环境中向最终用户展示,然后尝试调试问题所在。 ✨

24
fastapi/applications.py

@ -189,20 +189,20 @@ class FastAPI(Starlette):
# contextvars.
# This needs to happen after user middlewares because those create a
# new contextvars context copy by using a new AnyIO task group.
# The initial part of dependencies with yield is executed in the
# FastAPI code, inside all the middlewares, but the teardown part
# (after yield) is executed in the AsyncExitStack in this middleware,
# if the AsyncExitStack lived outside of the custom middlewares and
# contextvars were set in a dependency with yield in that internal
# The initial part of dependencies with 'yield' is executed in the
# FastAPI code, inside all the middlewares. However, the teardown part
# (after 'yield') is executed in the AsyncExitStack in this middleware.
# If the AsyncExitStack lived outside of the custom middlewares and
# contextvars were set in a dependency with 'yield' in that internal
# contextvars context, the values would not be available in the
# outside context of the AsyncExitStack.
# By putting the middleware and the AsyncExitStack here, inside all
# user middlewares, the code before and after yield in dependencies
# with yield is executed in the same contextvars context, so all values
# set in contextvars before yield is still available after yield as
# would be expected.
# outer context of the AsyncExitStack.
# By placing the middleware and the AsyncExitStack here, inside all
# user middlewares, the code before and after 'yield' in dependencies
# with 'yield' is executed in the same contextvars context. Thus, all values
# set in contextvars before 'yield' are still available after 'yield,' as
# expected.
# Additionally, by having this AsyncExitStack here, after the
# ExceptionMiddleware, now dependencies can catch handled exceptions,
# ExceptionMiddleware, dependencies can now catch handled exceptions,
# e.g. HTTPException, to customize the teardown code (e.g. DB session
# rollback).
Middleware(AsyncExitStackMiddleware),

3
tests/test_openapi_examples.py

@ -125,6 +125,9 @@ client = TestClient(app)
def test_call_api():
response = client.post("/examples/", json={"data": "example1"})
assert response.status_code == 200, response.text
response = client.get("/path_examples/foo")
assert response.status_code == 200, response.text

Loading…
Cancel
Save