mirror of https://github.com/tiangolo/fastapi.git
Merge branch 'master' into master
This commit is contained in:
commit
a7106ee082
|
|
@ -14,7 +14,7 @@ repos:
|
|||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.9.4
|
||||
rev: v0.11.2
|
||||
hooks:
|
||||
- id: ruff
|
||||
args:
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
tiangolo:
|
||||
login: tiangolo
|
||||
count: 723
|
||||
count: 730
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
|
||||
url: https://github.com/tiangolo
|
||||
dependabot:
|
||||
login: dependabot
|
||||
count: 94
|
||||
count: 98
|
||||
avatarUrl: https://avatars.githubusercontent.com/in/29110?v=4
|
||||
url: https://github.com/apps/dependabot
|
||||
alejsdev:
|
||||
login: alejsdev
|
||||
count: 47
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=356f39ff3f0211c720b06d3dbb060e98884085e3&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=843355286cea366cbb3a4fc3a14343bd4eceef55&v=4
|
||||
url: https://github.com/alejsdev
|
||||
github-actions:
|
||||
login: github-actions
|
||||
|
|
@ -25,7 +25,7 @@ Kludex:
|
|||
url: https://github.com/Kludex
|
||||
pre-commit-ci:
|
||||
login: pre-commit-ci
|
||||
count: 22
|
||||
count: 23
|
||||
avatarUrl: https://avatars.githubusercontent.com/in/68672?v=4
|
||||
url: https://github.com/apps/pre-commit-ci
|
||||
dmontagu:
|
||||
|
|
@ -70,7 +70,7 @@ vishnuvskvkl:
|
|||
url: https://github.com/vishnuvskvkl
|
||||
svlandeg:
|
||||
login: svlandeg
|
||||
count: 6
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4
|
||||
url: https://github.com/svlandeg
|
||||
alissadb:
|
||||
|
|
@ -171,7 +171,7 @@ hukkin:
|
|||
marcosmmb:
|
||||
login: marcosmmb
|
||||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6181089?u=b8567a842b38c5570c315b2b7ca766fa7be6721e&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6181089?u=03c50eec631857d84df5232890780d00a3f76903&v=4
|
||||
url: https://github.com/marcosmmb
|
||||
Serrones:
|
||||
login: Serrones
|
||||
|
|
@ -311,7 +311,7 @@ dconathan:
|
|||
Jamim:
|
||||
login: Jamim
|
||||
count: 2
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5607572?u=0cf3027bec78ba4f0b89802430c136bc69847d7a&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5607572?u=9ce0b6a6d1a5124e28b3c04d8d26827ca328713a&v=4
|
||||
url: https://github.com/Jamim
|
||||
svalouch:
|
||||
login: svalouch
|
||||
|
|
@ -366,7 +366,7 @@ sattosan:
|
|||
michaeloliverx:
|
||||
login: michaeloliverx
|
||||
count: 2
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/55017335?u=e606eb5cc397c07523be47637b1ee796904fbb59&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/55017335?u=efb0cb6e261ff64d862fafb91ee80fc2e1f8a2ed&v=4
|
||||
url: https://github.com/michaeloliverx
|
||||
voegtlel:
|
||||
login: voegtlel
|
||||
|
|
@ -528,3 +528,8 @@ DanielYang59:
|
|||
count: 2
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/80093591?u=63873f701c7c74aac83c906800a1dddc0bc8c92f&v=4
|
||||
url: https://github.com/DanielYang59
|
||||
blueswen:
|
||||
login: blueswen
|
||||
count: 2
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1564148?u=6d6b8cc8f2b5cef715e68d6175154a8a94d518ee&v=4
|
||||
url: https://github.com/blueswen
|
||||
|
|
|
|||
|
|
@ -411,3 +411,8 @@ Talks:
|
|||
author_link: https://twitter.com/chriswithers13
|
||||
link: https://www.youtube.com/watch?v=3DLwPcrE5mA
|
||||
title: 'PyCon UK 2019: FastAPI from the ground up'
|
||||
Taiwanese:
|
||||
- author: Blueswen
|
||||
author_link: https://github.com/blueswen
|
||||
link: https://www.youtube.com/watch?v=y3sumuoDq4w
|
||||
title: 'PyCon TW 2024: 全方位強化 Python 服務可觀測性:以 FastAPI 和 Grafana Stack 為例'
|
||||
|
|
|
|||
|
|
@ -9,11 +9,8 @@ sponsors:
|
|||
avatarUrl: https://avatars.githubusercontent.com/u/79945230?v=4
|
||||
url: https://github.com/Nixtla
|
||||
- login: andrew-propelauth
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/89474256?u=1188c27cb744bbec36447a2cfd4453126b2ddb5c&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/89474256?u=c98993dec8553c09d424ede67bbe86e5c35f48c9&v=4
|
||||
url: https://github.com/andrew-propelauth
|
||||
- login: liblaber
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/100821118?v=4
|
||||
url: https://github.com/liblaber
|
||||
- login: zanfaruqui
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/104461687?v=4
|
||||
url: https://github.com/zanfaruqui
|
||||
|
|
@ -71,7 +68,10 @@ sponsors:
|
|||
- login: acsone
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7601056?v=4
|
||||
url: https://github.com/acsone
|
||||
- - login: Trivie
|
||||
- - login: ecosyste-ms
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/98474690?v=4
|
||||
url: https://github.com/ecosyste-ms
|
||||
- login: Trivie
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8161763?v=4
|
||||
url: https://github.com/Trivie
|
||||
- - login: takashi-yoneya
|
||||
|
|
@ -86,6 +86,9 @@ sponsors:
|
|||
- login: yasyf
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/709645?u=f36736b3c6a85f578886ecc42a740e7b436e7a01&v=4
|
||||
url: https://github.com/yasyf
|
||||
- - login: alixlahuec
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/29543316?u=44357eb2a93bccf30fb9d389b8befe94a3d00985&v=4
|
||||
url: https://github.com/alixlahuec
|
||||
- - login: primer-io
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/62146168?v=4
|
||||
url: https://github.com/primer-io
|
||||
|
|
@ -101,27 +104,27 @@ sponsors:
|
|||
- - login: samuelcolvin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4039449?u=42eb3b833047c8c4b4f647a031eaef148c16d93f&v=4
|
||||
url: https://github.com/samuelcolvin
|
||||
- login: vincentkoc
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/25068?u=fbd5b2d51142daa4bdbc21e21953a3b8b8188a4a&v=4
|
||||
url: https://github.com/vincentkoc
|
||||
- login: ddilidili
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/42176885?u=c0a849dde06987434653197b5f638d3deb55fc6c&v=4
|
||||
url: https://github.com/ddilidili
|
||||
- login: ProteinQure
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/33707203?v=4
|
||||
url: https://github.com/ProteinQure
|
||||
- login: otosky
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/42260747?u=69d089387c743d89427aa4ad8740cfb34045a9e0&v=4
|
||||
url: https://github.com/otosky
|
||||
- login: ramonalmeidam
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/45269580?u=3358750b3a5854d7c3ed77aaca7dd20a0f529d32&v=4
|
||||
url: https://github.com/ramonalmeidam
|
||||
- login: mjohnsey
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16784016?u=38fad2e6b411244560b3af99c5f5a4751bc81865&v=4
|
||||
url: https://github.com/mjohnsey
|
||||
- login: ashi-agrawal
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/17105294?u=99c7a854035e5398d8e7b674f2d42baae6c957f8&v=4
|
||||
url: https://github.com/ashi-agrawal
|
||||
- login: sepsi77
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/18682303?v=4
|
||||
url: https://github.com/sepsi77
|
||||
- login: RaamEEIL
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/20320552?v=4
|
||||
url: https://github.com/RaamEEIL
|
||||
- login: jhundman
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/24263908?v=4
|
||||
url: https://github.com/jhundman
|
||||
- login: b-rad-c
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/25362581?u=5bb10629f4015b62bec1f9a366675d5085551af9&v=4
|
||||
url: https://github.com/b-rad-c
|
||||
|
|
@ -137,15 +140,6 @@ sponsors:
|
|||
- login: Leay15
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/32212558?u=c4aa9c1737e515959382a5515381757b1fd86c53&v=4
|
||||
url: https://github.com/Leay15
|
||||
- login: BoYanZh
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/32470225?u=55b174d080382822759d74307f8a0355fa86e808&v=4
|
||||
url: https://github.com/BoYanZh
|
||||
- login: ygorpontelo
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/32963605?u=35f7103f9c4c4c2589ae5737ee882e9375ef072e&v=4
|
||||
url: https://github.com/ygorpontelo
|
||||
- login: ProteinQure
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/33707203?v=4
|
||||
url: https://github.com/ProteinQure
|
||||
- login: chickenandstats
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/79477966?u=ae2b894aa954070db1d7830dab99b49eba4e4567&v=4
|
||||
url: https://github.com/chickenandstats
|
||||
|
|
@ -212,12 +206,9 @@ sponsors:
|
|||
- login: gorhack
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4141690?u=ec119ebc4bdf00a7bc84657a71aa17834f4f27f3&v=4
|
||||
url: https://github.com/gorhack
|
||||
- login: Ryandaydev
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4292423?u=48f68868db8886fce31a1d802c1003914c6cd7c6&v=4
|
||||
url: https://github.com/Ryandaydev
|
||||
- login: jaredtrog
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4381365?v=4
|
||||
url: https://github.com/jaredtrog
|
||||
- login: vincentkoc
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/25068?u=fbd5b2d51142daa4bdbc21e21953a3b8b8188a4a&v=4
|
||||
url: https://github.com/vincentkoc
|
||||
- login: jstanden
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/63288?u=c3658d57d2862c607a0e19c2101c3c51876e36ad&v=4
|
||||
url: https://github.com/jstanden
|
||||
|
|
@ -272,12 +263,12 @@ sponsors:
|
|||
- login: khadrawy
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/13686061?u=59f25ef42ecf04c22657aac4238ce0e2d3d30304&v=4
|
||||
url: https://github.com/khadrawy
|
||||
- login: mjohnsey
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16784016?u=38fad2e6b411244560b3af99c5f5a4751bc81865&v=4
|
||||
url: https://github.com/mjohnsey
|
||||
- login: ashi-agrawal
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/17105294?u=99c7a854035e5398d8e7b674f2d42baae6c957f8&v=4
|
||||
url: https://github.com/ashi-agrawal
|
||||
- login: Ryandaydev
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4292423?u=679ff84cb7b988c5795a5fa583857f574a055763&v=4
|
||||
url: https://github.com/Ryandaydev
|
||||
- login: jaredtrog
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4381365?v=4
|
||||
url: https://github.com/jaredtrog
|
||||
- login: oliverxchen
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4471774?u=534191f25e32eeaadda22dfab4b0a428733d5489&v=4
|
||||
url: https://github.com/oliverxchen
|
||||
|
|
@ -299,6 +290,9 @@ sponsors:
|
|||
- login: hiancdtrsnm
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7343177?v=4
|
||||
url: https://github.com/hiancdtrsnm
|
||||
- - login: jpizquierdo
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6716239?v=4
|
||||
url: https://github.com/jpizquierdo
|
||||
- - login: pawamoy
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3999221?u=b030e4c89df2f3a36bc4710b925bdeb6745c9856&v=4
|
||||
url: https://github.com/pawamoy
|
||||
|
|
@ -308,6 +302,9 @@ sponsors:
|
|||
- login: petercool
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/37613029?u=81c525232bb35780945a68e88afd96bb2cdad9c4&v=4
|
||||
url: https://github.com/petercool
|
||||
- login: diegopenilla
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/42318333?v=4
|
||||
url: https://github.com/diegopenilla
|
||||
- login: siavashyj
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/43583410?u=562005ddc7901cd27a1219a118a2363817b14977&v=4
|
||||
url: https://github.com/siavashyj
|
||||
|
|
@ -317,9 +314,9 @@ sponsors:
|
|||
- login: ArtyomVancyan
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/44609997?v=4
|
||||
url: https://github.com/ArtyomVancyan
|
||||
- login: caviri
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/45425937?u=4e14bd64282bad8f385eafbdb004b5a279366d6e&v=4
|
||||
url: https://github.com/caviri
|
||||
- login: joshuatz
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/17817563?u=f1bf05b690d1fc164218f0b420cdd3acb7913e21&v=4
|
||||
url: https://github.com/joshuatz
|
||||
- login: SebTota
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/25122511?v=4
|
||||
url: https://github.com/SebTota
|
||||
|
|
@ -341,6 +338,9 @@ sponsors:
|
|||
- login: engineerjoe440
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/33275230?u=eb223cad27017bb1e936ee9b429b450d092d0236&v=4
|
||||
url: https://github.com/engineerjoe440
|
||||
- login: caviri
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/45425937?u=4e14bd64282bad8f385eafbdb004b5a279366d6e&v=4
|
||||
url: https://github.com/caviri
|
||||
- login: hgalytoby
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/50397689?u=62c7ff3519858423579676cd0efbd7e3f1ffe63a&v=4
|
||||
url: https://github.com/hgalytoby
|
||||
|
|
@ -356,6 +356,9 @@ sponsors:
|
|||
- login: PelicanQ
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/77930606?v=4
|
||||
url: https://github.com/PelicanQ
|
||||
- login: tochikuji
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/851759?v=4
|
||||
url: https://github.com/tochikuji
|
||||
- login: browniebroke
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/861044?u=5abfca5588f3e906b31583d7ee62f6de4b68aa24&v=4
|
||||
url: https://github.com/browniebroke
|
||||
|
|
@ -386,9 +389,9 @@ sponsors:
|
|||
- login: ceb10n
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
|
||||
url: https://github.com/ceb10n
|
||||
- login: tochikuji
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/851759?v=4
|
||||
url: https://github.com/tochikuji
|
||||
- login: moonape1226
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8532038?u=d9f8b855a429fff9397c3833c2ff83849ebf989d&v=4
|
||||
url: https://github.com/moonape1226
|
||||
- login: msehnout
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9369632?u=8c988f1b008a3f601385a3616f9327820f66e3a5&v=4
|
||||
url: https://github.com/msehnout
|
||||
|
|
@ -419,9 +422,6 @@ sponsors:
|
|||
- login: TheR1D
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16740832?u=b0dfdbdb27b79729430c71c6128962f77b7b53f7&v=4
|
||||
url: https://github.com/TheR1D
|
||||
- login: joshuatz
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/17817563?u=f1bf05b690d1fc164218f0b420cdd3acb7913e21&v=4
|
||||
url: https://github.com/joshuatz
|
||||
- login: danielunderwood
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4472301?v=4
|
||||
url: https://github.com/danielunderwood
|
||||
|
|
@ -449,9 +449,6 @@ sponsors:
|
|||
- login: hcristea
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7814406?u=19092923a4ea5b338567961c8270b9206a6d81bb&v=4
|
||||
url: https://github.com/hcristea
|
||||
- login: moonape1226
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8532038?u=d9f8b855a429fff9397c3833c2ff83849ebf989d&v=4
|
||||
url: https://github.com/moonape1226
|
||||
- - login: larsyngvelundin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/34173819?u=74958599695bf83ac9f1addd935a51548a10c6b0&v=4
|
||||
url: https://github.com/larsyngvelundin
|
||||
|
|
@ -461,9 +458,9 @@ sponsors:
|
|||
- login: rwxd
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/40308458?u=cd04a39e3655923be4f25c2ba8a5a07b3da3230a&v=4
|
||||
url: https://github.com/rwxd
|
||||
- login: morzan1001
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/47593005?u=c30ab7230f82a12a9b938dcb54f84a996931409a&v=4
|
||||
url: https://github.com/morzan1001
|
||||
- login: kenkanayama
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/44771224?u=f68870c20c0f069491411aea8693c4714b40ecf0&v=4
|
||||
url: https://github.com/kenkanayama
|
||||
- login: sadikkuzu
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/23168063?u=d179c06bb9f65c4167fcab118526819f8e0dac17&v=4
|
||||
url: https://github.com/sadikkuzu
|
||||
|
|
@ -473,12 +470,12 @@ sponsors:
|
|||
- login: FabulousCodingFox
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/78906517?u=924a27cbee3db7e0ece5cc1509921402e1445e74&v=4
|
||||
url: https://github.com/FabulousCodingFox
|
||||
- login: anqorithm
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/61029571?u=468256fa4e2d9ce2870b608299724bebb7a33f18&v=4
|
||||
url: https://github.com/anqorithm
|
||||
- login: Materacl
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/70155818?u=ae11d084518856127cca483816a91a187e3124ee&v=4
|
||||
url: https://github.com/Materacl
|
||||
- login: morzan1001
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/47593005?u=c30ab7230f82a12a9b938dcb54f84a996931409a&v=4
|
||||
url: https://github.com/morzan1001
|
||||
- login: BrianCurliss
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1222949?v=4
|
||||
url: https://github.com/BrianCurliss
|
||||
- login: Toothwitch
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1710406?u=5eebb23b46cd26e48643b9e5179536cad491c17a&v=4
|
||||
url: https://github.com/Toothwitch
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,251 +1,251 @@
|
|||
- name: full-stack-fastapi-template
|
||||
html_url: https://github.com/fastapi/full-stack-fastapi-template
|
||||
stars: 30645
|
||||
stars: 31581
|
||||
owner_login: fastapi
|
||||
owner_html_url: https://github.com/fastapi
|
||||
- name: Hello-Python
|
||||
html_url: https://github.com/mouredev/Hello-Python
|
||||
stars: 28690
|
||||
stars: 29256
|
||||
owner_login: mouredev
|
||||
owner_html_url: https://github.com/mouredev
|
||||
- name: serve
|
||||
html_url: https://github.com/jina-ai/serve
|
||||
stars: 21356
|
||||
stars: 21487
|
||||
owner_login: jina-ai
|
||||
owner_html_url: https://github.com/jina-ai
|
||||
- name: sqlmodel
|
||||
html_url: https://github.com/fastapi/sqlmodel
|
||||
stars: 15312
|
||||
stars: 15521
|
||||
owner_login: fastapi
|
||||
owner_html_url: https://github.com/fastapi
|
||||
- name: HivisionIDPhotos
|
||||
html_url: https://github.com/Zeyi-Lin/HivisionIDPhotos
|
||||
stars: 14957
|
||||
stars: 15353
|
||||
owner_login: Zeyi-Lin
|
||||
owner_html_url: https://github.com/Zeyi-Lin
|
||||
- name: Douyin_TikTok_Download_API
|
||||
html_url: https://github.com/Evil0ctal/Douyin_TikTok_Download_API
|
||||
stars: 11192
|
||||
stars: 11719
|
||||
owner_login: Evil0ctal
|
||||
owner_html_url: https://github.com/Evil0ctal
|
||||
- name: fastapi-best-practices
|
||||
html_url: https://github.com/zhanymkanov/fastapi-best-practices
|
||||
stars: 10501
|
||||
stars: 11129
|
||||
owner_login: zhanymkanov
|
||||
owner_html_url: https://github.com/zhanymkanov
|
||||
- name: awesome-fastapi
|
||||
html_url: https://github.com/mjhea0/awesome-fastapi
|
||||
stars: 9193
|
||||
stars: 9387
|
||||
owner_login: mjhea0
|
||||
owner_html_url: https://github.com/mjhea0
|
||||
- name: FastUI
|
||||
html_url: https://github.com/pydantic/FastUI
|
||||
stars: 8721
|
||||
stars: 8787
|
||||
owner_login: pydantic
|
||||
owner_html_url: https://github.com/pydantic
|
||||
- name: nonebot2
|
||||
html_url: https://github.com/nonebot/nonebot2
|
||||
stars: 6433
|
||||
stars: 6596
|
||||
owner_login: nonebot
|
||||
owner_html_url: https://github.com/nonebot
|
||||
- name: serge
|
||||
html_url: https://github.com/serge-chat/serge
|
||||
stars: 5699
|
||||
owner_login: serge-chat
|
||||
owner_html_url: https://github.com/serge-chat
|
||||
- name: FileCodeBox
|
||||
html_url: https://github.com/vastsa/FileCodeBox
|
||||
stars: 5534
|
||||
stars: 6302
|
||||
owner_login: vastsa
|
||||
owner_html_url: https://github.com/vastsa
|
||||
- name: serge
|
||||
html_url: https://github.com/serge-chat/serge
|
||||
stars: 5707
|
||||
owner_login: serge-chat
|
||||
owner_html_url: https://github.com/serge-chat
|
||||
- name: fastapi-users
|
||||
html_url: https://github.com/fastapi-users/fastapi-users
|
||||
stars: 4921
|
||||
stars: 5045
|
||||
owner_login: fastapi-users
|
||||
owner_html_url: https://github.com/fastapi-users
|
||||
- name: polar
|
||||
html_url: https://github.com/polarsource/polar
|
||||
stars: 4598
|
||||
stars: 4870
|
||||
owner_login: polarsource
|
||||
owner_html_url: https://github.com/polarsource
|
||||
- name: hatchet
|
||||
html_url: https://github.com/hatchet-dev/hatchet
|
||||
stars: 4585
|
||||
stars: 4658
|
||||
owner_login: hatchet-dev
|
||||
owner_html_url: https://github.com/hatchet-dev
|
||||
- name: chatgpt-web-share
|
||||
html_url: https://github.com/chatpire/chatgpt-web-share
|
||||
stars: 4318
|
||||
stars: 4310
|
||||
owner_login: chatpire
|
||||
owner_html_url: https://github.com/chatpire
|
||||
- name: strawberry
|
||||
html_url: https://github.com/strawberry-graphql/strawberry
|
||||
stars: 4180
|
||||
stars: 4217
|
||||
owner_login: strawberry-graphql
|
||||
owner_html_url: https://github.com/strawberry-graphql
|
||||
- name: atrilabs-engine
|
||||
html_url: https://github.com/Atri-Labs/atrilabs-engine
|
||||
stars: 4114
|
||||
stars: 4111
|
||||
owner_login: Atri-Labs
|
||||
owner_html_url: https://github.com/Atri-Labs
|
||||
- name: dynaconf
|
||||
html_url: https://github.com/dynaconf/dynaconf
|
||||
stars: 3904
|
||||
stars: 3936
|
||||
owner_login: dynaconf
|
||||
owner_html_url: https://github.com/dynaconf
|
||||
- name: poem
|
||||
html_url: https://github.com/poem-web/poem
|
||||
stars: 3781
|
||||
stars: 3882
|
||||
owner_login: poem-web
|
||||
owner_html_url: https://github.com/poem-web
|
||||
- name: farfalle
|
||||
html_url: https://github.com/rashadphz/farfalle
|
||||
stars: 3190
|
||||
stars: 3248
|
||||
owner_login: rashadphz
|
||||
owner_html_url: https://github.com/rashadphz
|
||||
- name: opyrator
|
||||
html_url: https://github.com/ml-tooling/opyrator
|
||||
stars: 3119
|
||||
owner_login: ml-tooling
|
||||
owner_html_url: https://github.com/ml-tooling
|
||||
- name: fastapi-admin
|
||||
html_url: https://github.com/fastapi-admin/fastapi-admin
|
||||
stars: 3086
|
||||
stars: 3130
|
||||
owner_login: fastapi-admin
|
||||
owner_html_url: https://github.com/fastapi-admin
|
||||
- name: docarray
|
||||
html_url: https://github.com/docarray/docarray
|
||||
stars: 3021
|
||||
owner_login: docarray
|
||||
owner_html_url: https://github.com/docarray
|
||||
- name: opyrator
|
||||
html_url: https://github.com/ml-tooling/opyrator
|
||||
stars: 3116
|
||||
owner_login: ml-tooling
|
||||
owner_html_url: https://github.com/ml-tooling
|
||||
- name: datamodel-code-generator
|
||||
html_url: https://github.com/koxudaxi/datamodel-code-generator
|
||||
stars: 2988
|
||||
stars: 3054
|
||||
owner_login: koxudaxi
|
||||
owner_html_url: https://github.com/koxudaxi
|
||||
- name: docarray
|
||||
html_url: https://github.com/docarray/docarray
|
||||
stars: 3033
|
||||
owner_login: docarray
|
||||
owner_html_url: https://github.com/docarray
|
||||
- name: LitServe
|
||||
html_url: https://github.com/Lightning-AI/LitServe
|
||||
stars: 2863
|
||||
stars: 3019
|
||||
owner_login: Lightning-AI
|
||||
owner_html_url: https://github.com/Lightning-AI
|
||||
- name: fastapi-realworld-example-app
|
||||
html_url: https://github.com/nsidnev/fastapi-realworld-example-app
|
||||
stars: 2850
|
||||
owner_login: nsidnev
|
||||
owner_html_url: https://github.com/nsidnev
|
||||
- name: logfire
|
||||
html_url: https://github.com/pydantic/logfire
|
||||
stars: 2757
|
||||
stars: 2909
|
||||
owner_login: pydantic
|
||||
owner_html_url: https://github.com/pydantic
|
||||
- name: uvicorn-gunicorn-fastapi-docker
|
||||
html_url: https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker
|
||||
stars: 2731
|
||||
owner_login: tiangolo
|
||||
owner_html_url: https://github.com/tiangolo
|
||||
- name: fastapi-realworld-example-app
|
||||
html_url: https://github.com/nsidnev/fastapi-realworld-example-app
|
||||
stars: 2863
|
||||
owner_login: nsidnev
|
||||
owner_html_url: https://github.com/nsidnev
|
||||
- name: huma
|
||||
html_url: https://github.com/danielgtaylor/huma
|
||||
stars: 2700
|
||||
stars: 2861
|
||||
owner_login: danielgtaylor
|
||||
owner_html_url: https://github.com/danielgtaylor
|
||||
- name: uvicorn-gunicorn-fastapi-docker
|
||||
html_url: https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker
|
||||
stars: 2736
|
||||
owner_login: tiangolo
|
||||
owner_html_url: https://github.com/tiangolo
|
||||
- name: tracecat
|
||||
html_url: https://github.com/TracecatHQ/tracecat
|
||||
stars: 2539
|
||||
stars: 2556
|
||||
owner_login: TracecatHQ
|
||||
owner_html_url: https://github.com/TracecatHQ
|
||||
- name: best-of-web-python
|
||||
html_url: https://github.com/ml-tooling/best-of-web-python
|
||||
stars: 2460
|
||||
stars: 2485
|
||||
owner_login: ml-tooling
|
||||
owner_html_url: https://github.com/ml-tooling
|
||||
- name: RasaGPT
|
||||
html_url: https://github.com/paulpierre/RasaGPT
|
||||
stars: 2401
|
||||
stars: 2409
|
||||
owner_login: paulpierre
|
||||
owner_html_url: https://github.com/paulpierre
|
||||
- name: fastapi-react
|
||||
html_url: https://github.com/Buuntu/fastapi-react
|
||||
stars: 2315
|
||||
stars: 2337
|
||||
owner_login: Buuntu
|
||||
owner_html_url: https://github.com/Buuntu
|
||||
- name: nextpy
|
||||
html_url: https://github.com/dot-agent/nextpy
|
||||
stars: 2266
|
||||
stars: 2271
|
||||
owner_login: dot-agent
|
||||
owner_html_url: https://github.com/dot-agent
|
||||
- name: 30-Days-of-Python
|
||||
html_url: https://github.com/codingforentrepreneurs/30-Days-of-Python
|
||||
stars: 2163
|
||||
owner_login: codingforentrepreneurs
|
||||
owner_html_url: https://github.com/codingforentrepreneurs
|
||||
- name: FastAPI-template
|
||||
html_url: https://github.com/s3rius/FastAPI-template
|
||||
stars: 2156
|
||||
stars: 2223
|
||||
owner_login: s3rius
|
||||
owner_html_url: https://github.com/s3rius
|
||||
- name: Kokoro-FastAPI
|
||||
html_url: https://github.com/remsky/Kokoro-FastAPI
|
||||
stars: 2191
|
||||
owner_login: remsky
|
||||
owner_html_url: https://github.com/remsky
|
||||
- name: 30-Days-of-Python
|
||||
html_url: https://github.com/codingforentrepreneurs/30-Days-of-Python
|
||||
stars: 2172
|
||||
owner_login: codingforentrepreneurs
|
||||
owner_html_url: https://github.com/codingforentrepreneurs
|
||||
- name: sqladmin
|
||||
html_url: https://github.com/aminalaee/sqladmin
|
||||
stars: 2051
|
||||
stars: 2090
|
||||
owner_login: aminalaee
|
||||
owner_html_url: https://github.com/aminalaee
|
||||
- name: langserve
|
||||
html_url: https://github.com/langchain-ai/langserve
|
||||
stars: 2025
|
||||
stars: 2055
|
||||
owner_login: langchain-ai
|
||||
owner_html_url: https://github.com/langchain-ai
|
||||
- name: fastapi-utils
|
||||
html_url: https://github.com/fastapiutils/fastapi-utils
|
||||
stars: 2021
|
||||
stars: 2040
|
||||
owner_login: fastapiutils
|
||||
owner_html_url: https://github.com/fastapiutils
|
||||
- name: solara
|
||||
html_url: https://github.com/widgetti/solara
|
||||
stars: 1980
|
||||
stars: 2005
|
||||
owner_login: widgetti
|
||||
owner_html_url: https://github.com/widgetti
|
||||
- name: supabase-py
|
||||
html_url: https://github.com/supabase/supabase-py
|
||||
stars: 1874
|
||||
stars: 1936
|
||||
owner_login: supabase
|
||||
owner_html_url: https://github.com/supabase
|
||||
- name: python-week-2022
|
||||
html_url: https://github.com/rochacbruno/python-week-2022
|
||||
stars: 1829
|
||||
owner_login: rochacbruno
|
||||
owner_html_url: https://github.com/rochacbruno
|
||||
- name: mangum
|
||||
html_url: https://github.com/Kludex/mangum
|
||||
stars: 1820
|
||||
stars: 1852
|
||||
owner_login: Kludex
|
||||
owner_html_url: https://github.com/Kludex
|
||||
- name: Kokoro-FastAPI
|
||||
html_url: https://github.com/remsky/Kokoro-FastAPI
|
||||
stars: 1771
|
||||
owner_login: remsky
|
||||
owner_html_url: https://github.com/remsky
|
||||
- name: python-week-2022
|
||||
html_url: https://github.com/rochacbruno/python-week-2022
|
||||
stars: 1828
|
||||
owner_login: rochacbruno
|
||||
owner_html_url: https://github.com/rochacbruno
|
||||
- name: manage-fastapi
|
||||
html_url: https://github.com/ycd/manage-fastapi
|
||||
stars: 1719
|
||||
stars: 1730
|
||||
owner_login: ycd
|
||||
owner_html_url: https://github.com/ycd
|
||||
- name: ormar
|
||||
html_url: https://github.com/collerek/ormar
|
||||
stars: 1710
|
||||
stars: 1722
|
||||
owner_login: collerek
|
||||
owner_html_url: https://github.com/collerek
|
||||
- name: agentkit
|
||||
html_url: https://github.com/BCG-X-Official/agentkit
|
||||
stars: 1658
|
||||
stars: 1715
|
||||
owner_login: BCG-X-Official
|
||||
owner_html_url: https://github.com/BCG-X-Official
|
||||
- name: langchain-serve
|
||||
html_url: https://github.com/jina-ai/langchain-serve
|
||||
stars: 1618
|
||||
stars: 1625
|
||||
owner_login: jina-ai
|
||||
owner_html_url: https://github.com/jina-ai
|
||||
- name: termpair
|
||||
html_url: https://github.com/cs01/termpair
|
||||
stars: 1611
|
||||
stars: 1610
|
||||
owner_login: cs01
|
||||
owner_html_url: https://github.com/cs01
|
||||
- name: coronavirus-tracker-api
|
||||
|
|
@ -255,241 +255,241 @@
|
|||
owner_html_url: https://github.com/ExpDev07
|
||||
- name: piccolo
|
||||
html_url: https://github.com/piccolo-orm/piccolo
|
||||
stars: 1546
|
||||
stars: 1568
|
||||
owner_login: piccolo-orm
|
||||
owner_html_url: https://github.com/piccolo-orm
|
||||
- name: fastapi-cache
|
||||
html_url: https://github.com/long2ice/fastapi-cache
|
||||
stars: 1478
|
||||
stars: 1526
|
||||
owner_login: long2ice
|
||||
owner_html_url: https://github.com/long2ice
|
||||
- name: openapi-python-client
|
||||
html_url: https://github.com/openapi-generators/openapi-python-client
|
||||
stars: 1467
|
||||
stars: 1504
|
||||
owner_login: openapi-generators
|
||||
owner_html_url: https://github.com/openapi-generators
|
||||
- name: fastapi-crudrouter
|
||||
html_url: https://github.com/awtkns/fastapi-crudrouter
|
||||
stars: 1462
|
||||
stars: 1476
|
||||
owner_login: awtkns
|
||||
owner_html_url: https://github.com/awtkns
|
||||
- name: awesome-fastapi-projects
|
||||
html_url: https://github.com/Kludex/awesome-fastapi-projects
|
||||
stars: 1418
|
||||
stars: 1433
|
||||
owner_login: Kludex
|
||||
owner_html_url: https://github.com/Kludex
|
||||
- name: awesome-python-resources
|
||||
html_url: https://github.com/DjangoEx/awesome-python-resources
|
||||
stars: 1383
|
||||
owner_login: DjangoEx
|
||||
owner_html_url: https://github.com/DjangoEx
|
||||
- name: slowapi
|
||||
html_url: https://github.com/laurentS/slowapi
|
||||
stars: 1363
|
||||
stars: 1408
|
||||
owner_login: laurentS
|
||||
owner_html_url: https://github.com/laurentS
|
||||
- name: awesome-python-resources
|
||||
html_url: https://github.com/DjangoEx/awesome-python-resources
|
||||
stars: 1386
|
||||
owner_login: DjangoEx
|
||||
owner_html_url: https://github.com/DjangoEx
|
||||
- name: budgetml
|
||||
html_url: https://github.com/ebhy/budgetml
|
||||
stars: 1344
|
||||
stars: 1343
|
||||
owner_login: ebhy
|
||||
owner_html_url: https://github.com/ebhy
|
||||
- name: fastapi-pagination
|
||||
html_url: https://github.com/uriyyo/fastapi-pagination
|
||||
stars: 1284
|
||||
stars: 1309
|
||||
owner_login: uriyyo
|
||||
owner_html_url: https://github.com/uriyyo
|
||||
- name: fastapi-boilerplate
|
||||
html_url: https://github.com/teamhide/fastapi-boilerplate
|
||||
stars: 1234
|
||||
stars: 1262
|
||||
owner_login: teamhide
|
||||
owner_html_url: https://github.com/teamhide
|
||||
- name: fastapi-tutorial
|
||||
html_url: https://github.com/liaogx/fastapi-tutorial
|
||||
stars: 1181
|
||||
stars: 1203
|
||||
owner_login: liaogx
|
||||
owner_html_url: https://github.com/liaogx
|
||||
- name: fastapi-amis-admin
|
||||
html_url: https://github.com/amisadmin/fastapi-amis-admin
|
||||
stars: 1164
|
||||
stars: 1195
|
||||
owner_login: amisadmin
|
||||
owner_html_url: https://github.com/amisadmin
|
||||
- name: SurfSense
|
||||
html_url: https://github.com/MODSetter/SurfSense
|
||||
stars: 1169
|
||||
owner_login: MODSetter
|
||||
owner_html_url: https://github.com/MODSetter
|
||||
- name: fastapi-code-generator
|
||||
html_url: https://github.com/koxudaxi/fastapi-code-generator
|
||||
stars: 1132
|
||||
stars: 1157
|
||||
owner_login: koxudaxi
|
||||
owner_html_url: https://github.com/koxudaxi
|
||||
- name: bolt-python
|
||||
html_url: https://github.com/slackapi/bolt-python
|
||||
stars: 1130
|
||||
stars: 1143
|
||||
owner_login: slackapi
|
||||
owner_html_url: https://github.com/slackapi
|
||||
- name: langchain-extract
|
||||
html_url: https://github.com/langchain-ai/langchain-extract
|
||||
stars: 1110
|
||||
stars: 1122
|
||||
owner_login: langchain-ai
|
||||
owner_html_url: https://github.com/langchain-ai
|
||||
- name: odmantic
|
||||
html_url: https://github.com/art049/odmantic
|
||||
stars: 1104
|
||||
owner_login: art049
|
||||
owner_html_url: https://github.com/art049
|
||||
- name: fastapi_production_template
|
||||
html_url: https://github.com/zhanymkanov/fastapi_production_template
|
||||
stars: 1093
|
||||
stars: 1112
|
||||
owner_login: zhanymkanov
|
||||
owner_html_url: https://github.com/zhanymkanov
|
||||
- name: SurfSense
|
||||
html_url: https://github.com/MODSetter/SurfSense
|
||||
stars: 1081
|
||||
owner_login: MODSetter
|
||||
owner_html_url: https://github.com/MODSetter
|
||||
- name: fastapi-alembic-sqlmodel-async
|
||||
html_url: https://github.com/jonra1993/fastapi-alembic-sqlmodel-async
|
||||
stars: 1063
|
||||
owner_login: jonra1993
|
||||
owner_html_url: https://github.com/jonra1993
|
||||
- name: odmantic
|
||||
html_url: https://github.com/art049/odmantic
|
||||
stars: 1109
|
||||
owner_login: art049
|
||||
owner_html_url: https://github.com/art049
|
||||
- name: prometheus-fastapi-instrumentator
|
||||
html_url: https://github.com/trallnag/prometheus-fastapi-instrumentator
|
||||
stars: 1059
|
||||
stars: 1091
|
||||
owner_login: trallnag
|
||||
owner_html_url: https://github.com/trallnag
|
||||
- name: bedrock-claude-chat
|
||||
html_url: https://github.com/aws-samples/bedrock-claude-chat
|
||||
stars: 1039
|
||||
owner_login: aws-samples
|
||||
owner_html_url: https://github.com/aws-samples
|
||||
- name: runhouse
|
||||
html_url: https://github.com/run-house/runhouse
|
||||
stars: 1005
|
||||
owner_login: run-house
|
||||
owner_html_url: https://github.com/run-house
|
||||
- name: vue-fastapi-admin
|
||||
html_url: https://github.com/mizhexiaoxiao/vue-fastapi-admin
|
||||
stars: 987
|
||||
stars: 1086
|
||||
owner_login: mizhexiaoxiao
|
||||
owner_html_url: https://github.com/mizhexiaoxiao
|
||||
- name: bedrock-claude-chat
|
||||
html_url: https://github.com/aws-samples/bedrock-claude-chat
|
||||
stars: 1075
|
||||
owner_login: aws-samples
|
||||
owner_html_url: https://github.com/aws-samples
|
||||
- name: fastapi-alembic-sqlmodel-async
|
||||
html_url: https://github.com/jonra1993/fastapi-alembic-sqlmodel-async
|
||||
stars: 1074
|
||||
owner_login: jonra1993
|
||||
owner_html_url: https://github.com/jonra1993
|
||||
- name: runhouse
|
||||
html_url: https://github.com/run-house/runhouse
|
||||
stars: 1016
|
||||
owner_login: run-house
|
||||
owner_html_url: https://github.com/run-house
|
||||
- name: restish
|
||||
html_url: https://github.com/danielgtaylor/restish
|
||||
stars: 1012
|
||||
owner_login: danielgtaylor
|
||||
owner_html_url: https://github.com/danielgtaylor
|
||||
- name: lanarky
|
||||
html_url: https://github.com/ajndkr/lanarky
|
||||
stars: 986
|
||||
stars: 988
|
||||
owner_login: ajndkr
|
||||
owner_html_url: https://github.com/ajndkr
|
||||
- name: autollm
|
||||
html_url: https://github.com/viddexa/autollm
|
||||
stars: 986
|
||||
stars: 987
|
||||
owner_login: viddexa
|
||||
owner_html_url: https://github.com/viddexa
|
||||
- name: restish
|
||||
html_url: https://github.com/danielgtaylor/restish
|
||||
stars: 984
|
||||
owner_login: danielgtaylor
|
||||
owner_html_url: https://github.com/danielgtaylor
|
||||
- name: fastcrud
|
||||
html_url: https://github.com/igorbenav/fastcrud
|
||||
stars: 964
|
||||
stars: 985
|
||||
owner_login: igorbenav
|
||||
owner_html_url: https://github.com/igorbenav
|
||||
- name: secure
|
||||
html_url: https://github.com/TypeError/secure
|
||||
stars: 928
|
||||
stars: 930
|
||||
owner_login: TypeError
|
||||
owner_html_url: https://github.com/TypeError
|
||||
- name: langcorn
|
||||
html_url: https://github.com/msoedov/langcorn
|
||||
stars: 916
|
||||
stars: 924
|
||||
owner_login: msoedov
|
||||
owner_html_url: https://github.com/msoedov
|
||||
- name: fastapi_best_architecture
|
||||
html_url: https://github.com/fastapi-practices/fastapi_best_architecture
|
||||
stars: 921
|
||||
owner_login: fastapi-practices
|
||||
owner_html_url: https://github.com/fastapi-practices
|
||||
- name: energy-forecasting
|
||||
html_url: https://github.com/iusztinpaul/energy-forecasting
|
||||
stars: 898
|
||||
stars: 903
|
||||
owner_login: iusztinpaul
|
||||
owner_html_url: https://github.com/iusztinpaul
|
||||
- name: authx
|
||||
html_url: https://github.com/yezz123/authx
|
||||
stars: 874
|
||||
stars: 900
|
||||
owner_login: yezz123
|
||||
owner_html_url: https://github.com/yezz123
|
||||
- name: titiler
|
||||
html_url: https://github.com/developmentseed/titiler
|
||||
stars: 841
|
||||
owner_login: developmentseed
|
||||
owner_html_url: https://github.com/developmentseed
|
||||
- name: FastAPI-boilerplate
|
||||
html_url: https://github.com/igorbenav/FastAPI-boilerplate
|
||||
stars: 820
|
||||
stars: 877
|
||||
owner_login: igorbenav
|
||||
owner_html_url: https://github.com/igorbenav
|
||||
- name: titiler
|
||||
html_url: https://github.com/developmentseed/titiler
|
||||
stars: 853
|
||||
owner_login: developmentseed
|
||||
owner_html_url: https://github.com/developmentseed
|
||||
- name: ludic
|
||||
html_url: https://github.com/getludic/ludic
|
||||
stars: 831
|
||||
owner_login: getludic
|
||||
owner_html_url: https://github.com/getludic
|
||||
- name: marker-api
|
||||
html_url: https://github.com/adithya-s-k/marker-api
|
||||
stars: 813
|
||||
stars: 829
|
||||
owner_login: adithya-s-k
|
||||
owner_html_url: https://github.com/adithya-s-k
|
||||
- name: fastapi_best_architecture
|
||||
html_url: https://github.com/fastapi-practices/fastapi_best_architecture
|
||||
stars: 802
|
||||
owner_login: fastapi-practices
|
||||
owner_html_url: https://github.com/fastapi-practices
|
||||
- name: fastapi-observability
|
||||
html_url: https://github.com/blueswen/fastapi-observability
|
||||
stars: 771
|
||||
owner_login: blueswen
|
||||
owner_html_url: https://github.com/blueswen
|
||||
- name: fastapi-do-zero
|
||||
html_url: https://github.com/dunossauro/fastapi-do-zero
|
||||
stars: 745
|
||||
stars: 767
|
||||
owner_login: dunossauro
|
||||
owner_html_url: https://github.com/dunossauro
|
||||
- name: fastapi-mail
|
||||
html_url: https://github.com/sabuhish/fastapi-mail
|
||||
stars: 744
|
||||
stars: 759
|
||||
owner_login: sabuhish
|
||||
owner_html_url: https://github.com/sabuhish
|
||||
- name: fastapi-observability
|
||||
html_url: https://github.com/blueswen/fastapi-observability
|
||||
stars: 743
|
||||
owner_login: blueswen
|
||||
owner_html_url: https://github.com/blueswen
|
||||
- name: lccn_predictor
|
||||
html_url: https://github.com/baoliay2008/lccn_predictor
|
||||
stars: 741
|
||||
stars: 749
|
||||
owner_login: baoliay2008
|
||||
owner_html_url: https://github.com/baoliay2008
|
||||
- name: annotated-py-projects
|
||||
html_url: https://github.com/hhstore/annotated-py-projects
|
||||
stars: 727
|
||||
owner_login: hhstore
|
||||
owner_html_url: https://github.com/hhstore
|
||||
- name: learn-generative-ai
|
||||
html_url: https://github.com/panaverse/learn-generative-ai
|
||||
stars: 714
|
||||
owner_login: panaverse
|
||||
owner_html_url: https://github.com/panaverse
|
||||
- name: flock
|
||||
html_url: https://github.com/Onelevenvy/flock
|
||||
stars: 746
|
||||
owner_login: Onelevenvy
|
||||
owner_html_url: https://github.com/Onelevenvy
|
||||
- name: starlette-admin
|
||||
html_url: https://github.com/jowilf/starlette-admin
|
||||
stars: 713
|
||||
stars: 737
|
||||
owner_login: jowilf
|
||||
owner_html_url: https://github.com/jowilf
|
||||
- name: annotated-py-projects
|
||||
html_url: https://github.com/hhstore/annotated-py-projects
|
||||
stars: 729
|
||||
owner_login: hhstore
|
||||
owner_html_url: https://github.com/hhstore
|
||||
- name: KonomiTV
|
||||
html_url: https://github.com/tsukumijima/KonomiTV
|
||||
stars: 727
|
||||
owner_login: tsukumijima
|
||||
owner_html_url: https://github.com/tsukumijima
|
||||
- name: learn-generative-ai
|
||||
html_url: https://github.com/panaverse/learn-generative-ai
|
||||
stars: 725
|
||||
owner_login: panaverse
|
||||
owner_html_url: https://github.com/panaverse
|
||||
- name: FastAPI-Backend-Template
|
||||
html_url: https://github.com/Aeternalis-Ingenium/FastAPI-Backend-Template
|
||||
stars: 719
|
||||
owner_login: Aeternalis-Ingenium
|
||||
owner_html_url: https://github.com/Aeternalis-Ingenium
|
||||
- name: chatGPT-web
|
||||
html_url: https://github.com/mic1on/chatGPT-web
|
||||
stars: 712
|
||||
owner_login: mic1on
|
||||
owner_html_url: https://github.com/mic1on
|
||||
- name: FastAPI-Backend-Template
|
||||
html_url: https://github.com/Aeternalis-Ingenium/FastAPI-Backend-Template
|
||||
stars: 709
|
||||
owner_login: Aeternalis-Ingenium
|
||||
owner_html_url: https://github.com/Aeternalis-Ingenium
|
||||
- name: linbing
|
||||
html_url: https://github.com/taomujian/linbing
|
||||
stars: 698
|
||||
owner_login: taomujian
|
||||
owner_html_url: https://github.com/taomujian
|
||||
- name: KonomiTV
|
||||
html_url: https://github.com/tsukumijima/KonomiTV
|
||||
stars: 687
|
||||
owner_login: tsukumijima
|
||||
owner_html_url: https://github.com/tsukumijima
|
||||
- name: fastapi-jwt-auth
|
||||
html_url: https://github.com/IndominusByte/fastapi-jwt-auth
|
||||
stars: 685
|
||||
owner_login: IndominusByte
|
||||
owner_html_url: https://github.com/IndominusByte
|
||||
- name: pity
|
||||
html_url: https://github.com/wuranxu/pity
|
||||
stars: 667
|
||||
owner_login: wuranxu
|
||||
owner_html_url: https://github.com/wuranxu
|
||||
|
|
|
|||
|
|
@ -8,16 +8,16 @@ Xewus:
|
|||
count: 140
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/85196001?u=f8e2dc7e5104f109cef944af79050ea8d1b8f914&v=4
|
||||
url: https://github.com/Xewus
|
||||
sodaMelon:
|
||||
login: sodaMelon
|
||||
count: 113
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/66295123?u=be939db90f1119efee9e6110cc05066ff1f40f00&v=4
|
||||
url: https://github.com/sodaMelon
|
||||
ceb10n:
|
||||
login: ceb10n
|
||||
count: 112
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
|
||||
url: https://github.com/ceb10n
|
||||
sodaMelon:
|
||||
login: sodaMelon
|
||||
count: 111
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/66295123?u=be939db90f1119efee9e6110cc05066ff1f40f00&v=4
|
||||
url: https://github.com/sodaMelon
|
||||
tokusumi:
|
||||
login: tokusumi
|
||||
count: 104
|
||||
|
|
@ -33,6 +33,11 @@ hard-coders:
|
|||
count: 92
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
|
||||
url: https://github.com/hard-coders
|
||||
alv2017:
|
||||
login: alv2017
|
||||
count: 86
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
|
||||
url: https://github.com/alv2017
|
||||
nazarepiedady:
|
||||
login: nazarepiedady
|
||||
count: 83
|
||||
|
|
@ -43,11 +48,6 @@ AlertRED:
|
|||
count: 81
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/15695000?u=f5a4944c6df443030409c88da7d7fa0b7ead985c&v=4
|
||||
url: https://github.com/AlertRED
|
||||
alv2017:
|
||||
login: alv2017
|
||||
count: 81
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
|
||||
url: https://github.com/alv2017
|
||||
Alexandrhub:
|
||||
login: Alexandrhub
|
||||
count: 68
|
||||
|
|
@ -65,12 +65,12 @@ cassiobotaro:
|
|||
url: https://github.com/cassiobotaro
|
||||
mattwang44:
|
||||
login: mattwang44
|
||||
count: 58
|
||||
count: 59
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/24987826?u=58e37fb3927b9124b458945ac4c97aa0f1062d85&v=4
|
||||
url: https://github.com/mattwang44
|
||||
tiangolo:
|
||||
login: tiangolo
|
||||
count: 51
|
||||
count: 52
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
|
||||
url: https://github.com/tiangolo
|
||||
Laineyzhang55:
|
||||
|
|
@ -88,16 +88,26 @@ komtaki:
|
|||
count: 45
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/39375566?u=260ad6b1a4b34c07dbfa728da5e586f16f6d1824&v=4
|
||||
url: https://github.com/komtaki
|
||||
rostik1410:
|
||||
login: rostik1410
|
||||
count: 42
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11443899?u=e26a635c2ba220467b308a326a579b8ccf4a8701&v=4
|
||||
url: https://github.com/rostik1410
|
||||
svlandeg:
|
||||
login: svlandeg
|
||||
count: 42
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4
|
||||
url: https://github.com/svlandeg
|
||||
alperiox:
|
||||
login: alperiox
|
||||
count: 42
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/34214152?u=2c5acad3461d4dbc2d48371ba86cac56ae9b25cc&v=4
|
||||
url: https://github.com/alperiox
|
||||
rostik1410:
|
||||
login: rostik1410
|
||||
Rishat-F:
|
||||
login: Rishat-F
|
||||
count: 41
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11443899?u=e26a635c2ba220467b308a326a579b8ccf4a8701&v=4
|
||||
url: https://github.com/rostik1410
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/66554797?v=4
|
||||
url: https://github.com/Rishat-F
|
||||
Winand:
|
||||
login: Winand
|
||||
count: 40
|
||||
|
|
@ -126,7 +136,7 @@ SwftAlpc:
|
|||
alejsdev:
|
||||
login: alejsdev
|
||||
count: 36
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=356f39ff3f0211c720b06d3dbb060e98884085e3&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=843355286cea366cbb3a4fc3a14343bd4eceef55&v=4
|
||||
url: https://github.com/alejsdev
|
||||
timothy-jeong:
|
||||
login: timothy-jeong
|
||||
|
|
@ -138,16 +148,6 @@ nilslindemann:
|
|||
count: 35
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6892179?u=1dca6a22195d6cd1ab20737c0e19a4c55d639472&v=4
|
||||
url: https://github.com/nilslindemann
|
||||
svlandeg:
|
||||
login: svlandeg
|
||||
count: 35
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4
|
||||
url: https://github.com/svlandeg
|
||||
Rishat-F:
|
||||
login: Rishat-F
|
||||
count: 35
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/66554797?v=4
|
||||
url: https://github.com/Rishat-F
|
||||
rjNemo:
|
||||
login: rjNemo
|
||||
count: 34
|
||||
|
|
@ -158,6 +158,11 @@ codingjenny:
|
|||
count: 34
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/103817302?u=3a042740dc0ff58615da0d8679230966fd7693e8&v=4
|
||||
url: https://github.com/codingjenny
|
||||
mezgoodle:
|
||||
login: mezgoodle
|
||||
count: 33
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/41520940?u=4a9c765af688389d54296845d18b8f6cd6ddf09a&v=4
|
||||
url: https://github.com/mezgoodle
|
||||
akarev0:
|
||||
login: akarev0
|
||||
count: 33
|
||||
|
|
@ -178,6 +183,11 @@ LorhanSohaky:
|
|||
count: 30
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16273730?u=095b66f243a2cd6a0aadba9a095009f8aaf18393&v=4
|
||||
url: https://github.com/LorhanSohaky
|
||||
Vincy1230:
|
||||
login: Vincy1230
|
||||
count: 30
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/81342412?u=ab5e256a4077a4a91f3f9cd2115ba80780454cbe&v=4
|
||||
url: https://github.com/Vincy1230
|
||||
black-redoc:
|
||||
login: black-redoc
|
||||
count: 29
|
||||
|
|
@ -201,7 +211,7 @@ dedkot01:
|
|||
hsuanchi:
|
||||
login: hsuanchi
|
||||
count: 28
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/24913710?u=0b094ae292292fee093818e37ceb645c114d2bff&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/24913710?u=7d25a398e478b6e63503bf6f26c54efa9e0da07b&v=4
|
||||
url: https://github.com/hsuanchi
|
||||
dpinezich:
|
||||
login: dpinezich
|
||||
|
|
@ -228,16 +238,6 @@ junah201:
|
|||
count: 26
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/75025529?u=2451c256e888fa2a06bcfc0646d09b87ddb6a945&v=4
|
||||
url: https://github.com/junah201
|
||||
mezgoodle:
|
||||
login: mezgoodle
|
||||
count: 26
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/41520940?u=e871bc26734eb2436d98c19c3fb57a4773e13c24&v=4
|
||||
url: https://github.com/mezgoodle
|
||||
Vincy1230:
|
||||
login: Vincy1230
|
||||
count: 26
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/81342412?u=ab5e256a4077a4a91f3f9cd2115ba80780454cbe&v=4
|
||||
url: https://github.com/Vincy1230
|
||||
zy7y:
|
||||
login: zy7y
|
||||
count: 25
|
||||
|
|
@ -376,8 +376,13 @@ Joao-Pedro-P-Holanda:
|
|||
JaeHyuckSa:
|
||||
login: JaeHyuckSa
|
||||
count: 16
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/104830931?v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/104830931?u=b19b3e24d6030f88d22bd3e953f9525d2f062da3&v=4
|
||||
url: https://github.com/JaeHyuckSa
|
||||
SofiiaTrufanova:
|
||||
login: SofiiaTrufanova
|
||||
count: 16
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/63260929?u=483e0b64fabc76343b3be39b7e1dcb930a95e1bb&v=4
|
||||
url: https://github.com/SofiiaTrufanova
|
||||
Jedore:
|
||||
login: Jedore
|
||||
count: 15
|
||||
|
|
@ -411,8 +416,13 @@ BORA040126:
|
|||
mattkoehne:
|
||||
login: mattkoehne
|
||||
count: 14
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/80362153?u=6e1439582715693407b86182eb66263bb578a761&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/80362153?v=4
|
||||
url: https://github.com/mattkoehne
|
||||
DianaTrufanova:
|
||||
login: DianaTrufanova
|
||||
count: 14
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/119067607?u=1cd55f841b68b4a187fa6d06a7dafa5f070195aa&v=4
|
||||
url: https://github.com/DianaTrufanova
|
||||
jovicon:
|
||||
login: jovicon
|
||||
count: 13
|
||||
|
|
@ -706,7 +716,7 @@ KimJoonSeo:
|
|||
MinLee0210:
|
||||
login: MinLee0210
|
||||
count: 8
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/57653278?u=7def7c0654ad82f43b46d6dfc3b51c4d2be15011&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/57653278?u=25f979af418692b95e907df93607a09117e14b53&v=4
|
||||
url: https://github.com/MinLee0210
|
||||
camigomezdev:
|
||||
login: camigomezdev
|
||||
|
|
@ -718,6 +728,11 @@ maru0123-2004:
|
|||
count: 8
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/43961566?u=16ed8603a4d6a4665cb6c53a7aece6f31379b769&v=4
|
||||
url: https://github.com/maru0123-2004
|
||||
minaton-ru:
|
||||
login: minaton-ru
|
||||
count: 8
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/53541518?u=67336ca11a85493f75031508aade588dad3b9910&v=4
|
||||
url: https://github.com/minaton-ru
|
||||
Serrones:
|
||||
login: Serrones
|
||||
count: 7
|
||||
|
|
@ -873,16 +888,11 @@ bankofsardine:
|
|||
count: 6
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/44944207?u=0368e1b698ffab6bf29e202f9fd2dddd352429f1&v=4
|
||||
url: https://github.com/bankofsardine
|
||||
SofiiaTrufanova:
|
||||
login: SofiiaTrufanova
|
||||
valentinDruzhinin:
|
||||
login: valentinDruzhinin
|
||||
count: 6
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/63260929?v=4
|
||||
url: https://github.com/SofiiaTrufanova
|
||||
DianaTrufanova:
|
||||
login: DianaTrufanova
|
||||
count: 6
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/119067607?v=4
|
||||
url: https://github.com/DianaTrufanova
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/12831905?u=aae1ebc675c91e8fa582df4fcc4fc4128106344d&v=4
|
||||
url: https://github.com/valentinDruzhinin
|
||||
rsip22:
|
||||
login: rsip22
|
||||
count: 5
|
||||
|
|
@ -911,7 +921,7 @@ TemaSpb:
|
|||
BugLight:
|
||||
login: BugLight
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/13618366?u=57572e544e40c2a491db5bf7255bd24886d2cb09&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/13618366?u=7d733749f80e5f7e66a434cf42aedcfc60340f43&v=4
|
||||
url: https://github.com/BugLight
|
||||
0x4Dark:
|
||||
login: 0x4Dark
|
||||
|
|
@ -998,6 +1008,11 @@ devluisrodrigues:
|
|||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/103431660?u=d9674a3249edc4601d2c712cdebf899918503c3a&v=4
|
||||
url: https://github.com/devluisrodrigues
|
||||
Zerohertz:
|
||||
login: Zerohertz
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/42334717?u=c6acda352c866b1747921e0ff8782b58571d849e&v=4
|
||||
url: https://github.com/Zerohertz
|
||||
11kkw:
|
||||
login: 11kkw
|
||||
count: 5
|
||||
|
|
@ -1033,6 +1048,11 @@ FelipeSilva93:
|
|||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/66804965?u=e7cb4b580e46f2e04ecb4cd4d7a12acdddd3c6c1&v=4
|
||||
url: https://github.com/FelipeSilva93
|
||||
peacekimjapan:
|
||||
login: peacekimjapan
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/33534175?u=e4219bcebc3773a7068cc34c3eb268ef77cec31b&v=4
|
||||
url: https://github.com/peacekimjapan
|
||||
bas-baskara:
|
||||
login: bas-baskara
|
||||
count: 4
|
||||
|
|
@ -1061,7 +1081,7 @@ aminalaee:
|
|||
erfan-rfmhr:
|
||||
login: erfan-rfmhr
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/98986056?u=6c4f9218fe5bb04780dd92bfced360c55e2009f0&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/98986056?u=b1559d684b1ced11b2204546fa3cf28addf665a8&v=4
|
||||
url: https://github.com/erfan-rfmhr
|
||||
Scorpionchiques:
|
||||
login: Scorpionchiques
|
||||
|
|
@ -1123,11 +1143,11 @@ gerry-sabar:
|
|||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1120123?v=4
|
||||
url: https://github.com/gerry-sabar
|
||||
valentinDruzhinin:
|
||||
login: valentinDruzhinin
|
||||
cookie-byte217:
|
||||
login: cookie-byte217
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/12831905?u=aae1ebc675c91e8fa582df4fcc4fc4128106344d&v=4
|
||||
url: https://github.com/valentinDruzhinin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/57880178?v=4
|
||||
url: https://github.com/cookie-byte217
|
||||
tyronedamasceno:
|
||||
login: tyronedamasceno
|
||||
count: 3
|
||||
|
|
@ -1206,7 +1226,7 @@ RuslanTer:
|
|||
FedorGN:
|
||||
login: FedorGN
|
||||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/66411909?u=1c6734e92f50c7d66f130ef7d394e72b53770fe6&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/66411909?u=22382380e7d66ee57ffbfc2ae6bd5efd0cdb672e&v=4
|
||||
url: https://github.com/FedorGN
|
||||
rafsaf:
|
||||
login: rafsaf
|
||||
|
|
@ -1328,6 +1348,11 @@ kohiry:
|
|||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/57669492?u=f6ab0a062740261e882879269a41a47788c84043&v=4
|
||||
url: https://github.com/kohiry
|
||||
ptt3199:
|
||||
login: ptt3199
|
||||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/51350651?u=2c3d947a80283e32bf616d4c3af139a6be69680f&v=4
|
||||
url: https://github.com/ptt3199
|
||||
arynoot:
|
||||
login: arynoot
|
||||
count: 3
|
||||
|
|
@ -1353,16 +1378,21 @@ RyaWcksn:
|
|||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/42831964?u=0cb4265faf3e3425a89e59b6fddd3eb2de180af0&v=4
|
||||
url: https://github.com/RyaWcksn
|
||||
Zerohertz:
|
||||
login: Zerohertz
|
||||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/42334717?u=c6acda352c866b1747921e0ff8782b58571d849e&v=4
|
||||
url: https://github.com/Zerohertz
|
||||
tienduong-21:
|
||||
login: tienduong-21
|
||||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/80129618?v=4
|
||||
url: https://github.com/tienduong-21
|
||||
jameselite:
|
||||
login: jameselite
|
||||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/178516095?u=6964d633449bf7d4a83d0fa0198f81f9ee5cfcd0&v=4
|
||||
url: https://github.com/jameselite
|
||||
zbellos:
|
||||
login: zbellos
|
||||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/204500646?v=4
|
||||
url: https://github.com/zbellos
|
||||
blaisep:
|
||||
login: blaisep
|
||||
count: 2
|
||||
|
|
@ -1468,11 +1498,6 @@ lindsayzhou:
|
|||
count: 2
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/26602940?u=3c52ce6393bb547c97e6380ccdee03e0c64152c6&v=4
|
||||
url: https://github.com/0xflotus
|
||||
peacekimjapan:
|
||||
login: peacekimjapan
|
||||
count: 2
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/33534175?u=e4219bcebc3773a7068cc34c3eb268ef77cec31b&v=4
|
||||
url: https://github.com/peacekimjapan
|
||||
jonatasoli:
|
||||
login: jonatasoli
|
||||
count: 2
|
||||
|
|
@ -1656,7 +1681,7 @@ zhiquanchi:
|
|||
Jamim:
|
||||
login: Jamim
|
||||
count: 2
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5607572?u=0cf3027bec78ba4f0b89802430c136bc69847d7a&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5607572?u=9ce0b6a6d1a5124e28b3c04d8d26827ca328713a&v=4
|
||||
url: https://github.com/Jamim
|
||||
alvinkhalil:
|
||||
login: alvinkhalil
|
||||
|
|
@ -1666,7 +1691,7 @@ alvinkhalil:
|
|||
leylaeminova:
|
||||
login: leylaeminova
|
||||
count: 2
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/100516839?u=35a9ce14bb86d7d7faa25d432f61dec2984cb818&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/100516839?u=0b0dab9e31742076b22812b14a39b4e6d8f6de4a&v=4
|
||||
url: https://github.com/leylaeminova
|
||||
UN-9BOT:
|
||||
login: UN-9BOT
|
||||
|
|
@ -1678,11 +1703,6 @@ flasonme:
|
|||
count: 2
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/30571019?v=4
|
||||
url: https://github.com/flasonme
|
||||
ptt3199:
|
||||
login: ptt3199
|
||||
count: 2
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/51350651?u=ccf51f8820787e17983954f26b06acf226cba293&v=4
|
||||
url: https://github.com/ptt3199
|
||||
gustavoprezoto:
|
||||
login: gustavoprezoto
|
||||
count: 2
|
||||
|
|
@ -1733,3 +1753,13 @@ J-Fuji:
|
|||
count: 2
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/101452903?v=4
|
||||
url: https://github.com/J-Fuji
|
||||
MrL8199:
|
||||
login: MrL8199
|
||||
count: 2
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/39489075?u=3fc4f89c86973e40b5970d838c801bdbc13ac828&v=4
|
||||
url: https://github.com/MrL8199
|
||||
ivintoiu:
|
||||
login: ivintoiu
|
||||
count: 2
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1853336?u=5e3d0977f44661fb9712fa297cc8f7608ea6ce48&v=4
|
||||
url: https://github.com/ivintoiu
|
||||
|
|
|
|||
|
|
@ -33,6 +33,11 @@ waynerv:
|
|||
count: 20
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
|
||||
url: https://github.com/waynerv
|
||||
valentinDruzhinin:
|
||||
login: valentinDruzhinin
|
||||
count: 18
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/12831905?u=aae1ebc675c91e8fa582df4fcc4fc4128106344d&v=4
|
||||
url: https://github.com/valentinDruzhinin
|
||||
AlertRED:
|
||||
login: AlertRED
|
||||
count: 16
|
||||
|
|
@ -53,16 +58,16 @@ codingjenny:
|
|||
count: 14
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/103817302?u=3a042740dc0ff58615da0d8679230966fd7693e8&v=4
|
||||
url: https://github.com/codingjenny
|
||||
valentinDruzhinin:
|
||||
login: valentinDruzhinin
|
||||
count: 14
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/12831905?u=aae1ebc675c91e8fa582df4fcc4fc4128106344d&v=4
|
||||
url: https://github.com/valentinDruzhinin
|
||||
Xewus:
|
||||
login: Xewus
|
||||
count: 13
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/85196001?u=f8e2dc7e5104f109cef944af79050ea8d1b8f914&v=4
|
||||
url: https://github.com/Xewus
|
||||
Zhongheng-Cheng:
|
||||
login: Zhongheng-Cheng
|
||||
count: 13
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/95612344?u=a0f7730a3cc7486827965e01a119ad610bda4b0a&v=4
|
||||
url: https://github.com/Zhongheng-Cheng
|
||||
Smlep:
|
||||
login: Smlep
|
||||
count: 11
|
||||
|
|
@ -83,11 +88,6 @@ Vincy1230:
|
|||
count: 9
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/81342412?u=ab5e256a4077a4a91f3f9cd2115ba80780454cbe&v=4
|
||||
url: https://github.com/Vincy1230
|
||||
Zhongheng-Cheng:
|
||||
login: Zhongheng-Cheng
|
||||
count: 9
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/95612344?u=a0f7730a3cc7486827965e01a119ad610bda4b0a&v=4
|
||||
url: https://github.com/Zhongheng-Cheng
|
||||
rjNemo:
|
||||
login: rjNemo
|
||||
count: 8
|
||||
|
|
@ -103,6 +103,11 @@ pablocm83:
|
|||
count: 8
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/28315068?u=3310fbb05bb8bfc50d2c48b6cb64ac9ee4a14549&v=4
|
||||
url: https://github.com/pablocm83
|
||||
ptt3199:
|
||||
login: ptt3199
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/51350651?u=2c3d947a80283e32bf616d4c3af139a6be69680f&v=4
|
||||
url: https://github.com/ptt3199
|
||||
batlopes:
|
||||
login: batlopes
|
||||
count: 6
|
||||
|
|
@ -118,11 +123,6 @@ Alexandrhub:
|
|||
count: 6
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/119126536?u=9fc0d48f3307817bafecc5861eb2168401a6cb04&v=4
|
||||
url: https://github.com/Alexandrhub
|
||||
ptt3199:
|
||||
login: ptt3199
|
||||
count: 6
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/51350651?u=ccf51f8820787e17983954f26b06acf226cba293&v=4
|
||||
url: https://github.com/ptt3199
|
||||
Serrones:
|
||||
login: Serrones
|
||||
count: 5
|
||||
|
|
@ -203,6 +203,11 @@ kwang1215:
|
|||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/74170199?u=2a63ff6692119dde3f5e5693365b9fcd6f977b08&v=4
|
||||
url: https://github.com/kwang1215
|
||||
k94-ishi:
|
||||
login: k94-ishi
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/32672580?u=bc7c5c07af0656be9fe4f1784a444af8d81ded89&v=4
|
||||
url: https://github.com/k94-ishi
|
||||
jfunez:
|
||||
login: jfunez
|
||||
count: 3
|
||||
|
|
@ -271,12 +276,12 @@ mojtabapaso:
|
|||
hsuanchi:
|
||||
login: hsuanchi
|
||||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/24913710?u=0b094ae292292fee093818e37ceb645c114d2bff&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/24913710?u=7d25a398e478b6e63503bf6f26c54efa9e0da07b&v=4
|
||||
url: https://github.com/hsuanchi
|
||||
alejsdev:
|
||||
login: alejsdev
|
||||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=356f39ff3f0211c720b06d3dbb060e98884085e3&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=843355286cea366cbb3a4fc3a14343bd4eceef55&v=4
|
||||
url: https://github.com/alejsdev
|
||||
riroan:
|
||||
login: riroan
|
||||
|
|
@ -333,11 +338,6 @@ gerry-sabar:
|
|||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1120123?v=4
|
||||
url: https://github.com/gerry-sabar
|
||||
k94-ishi:
|
||||
login: k94-ishi
|
||||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/32672580?u=bc7c5c07af0656be9fe4f1784a444af8d81ded89&v=4
|
||||
url: https://github.com/k94-ishi
|
||||
Rishat-F:
|
||||
login: Rishat-F
|
||||
count: 3
|
||||
|
|
@ -513,3 +513,8 @@ timothy-jeong:
|
|||
count: 2
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/21125286?v=4
|
||||
url: https://github.com/11kkw
|
||||
yes0ng:
|
||||
login: yes0ng
|
||||
count: 2
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/25501794?u=3aed18b0d491e0220a167a1e9e58bea3638c6707&v=4
|
||||
url: https://github.com/yes0ng
|
||||
|
|
|
|||
|
|
@ -7,13 +7,53 @@ hide:
|
|||
|
||||
## Latest Changes
|
||||
|
||||
### Docs
|
||||
|
||||
* ✏️ Fix talk information typo. PR [#13544](https://github.com/fastapi/fastapi/pull/13544) by [@blueswen](https://github.com/blueswen).
|
||||
* 📝 Add External Link: Taiwanese talk on FastAPI with observability . PR [#13527](https://github.com/fastapi/fastapi/pull/13527) by [@blueswen](https://github.com/blueswen).
|
||||
|
||||
### Translations
|
||||
|
||||
* 🌐 Add Russian translation for `docs/ru/docs/tutorial/header-param-models.md`. PR [#13526](https://github.com/fastapi/fastapi/pull/13526) by [@minaton-ru](https://github.com/minaton-ru).
|
||||
* 🌐 Update Chinese translation for `docs/zh/docs/tutorial/index.md`. PR [#13374](https://github.com/fastapi/fastapi/pull/13374) by [@Zhongheng-Cheng](https://github.com/Zhongheng-Cheng).
|
||||
* 🌐 Update Chinese translation for `docs/zh/docs/deployment/manually.md`. PR [#13324](https://github.com/fastapi/fastapi/pull/13324) by [@Zhongheng-Cheng](https://github.com/Zhongheng-Cheng).
|
||||
* 🌐 Update Chinese translation for `docs/zh/docs/deployment/server-workers.md`. PR [#13292](https://github.com/fastapi/fastapi/pull/13292) by [@Zhongheng-Cheng](https://github.com/Zhongheng-Cheng).
|
||||
* 🌐 Update Chinese translation for `docs/zh/docs/tutorial/first-steps.md`. PR [#13348](https://github.com/fastapi/fastapi/pull/13348) by [@Zhongheng-Cheng](https://github.com/Zhongheng-Cheng).
|
||||
|
||||
### Internal
|
||||
|
||||
* 👥 Update FastAPI People - Experts. PR [#13568](https://github.com/fastapi/fastapi/pull/13568) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 👥 Update FastAPI GitHub topic repositories. PR [#13565](https://github.com/fastapi/fastapi/pull/13565) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 👥 Update FastAPI People - Sponsors. PR [#13559](https://github.com/fastapi/fastapi/pull/13559) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 👥 Update FastAPI People - Contributors and Translators. PR [#13558](https://github.com/fastapi/fastapi/pull/13558) by [@tiangolo](https://github.com/tiangolo).
|
||||
* ⬆ Bump dirty-equals from 0.8.0 to 0.9.0. PR [#13561](https://github.com/fastapi/fastapi/pull/13561) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
||||
* 🔧 Clean up `docs/en/mkdocs.yml` configuration file. PR [#13542](https://github.com/fastapi/fastapi/pull/13542) by [@svlandeg](https://github.com/svlandeg).
|
||||
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#12986](https://github.com/fastapi/fastapi/pull/12986) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
|
||||
|
||||
## 0.115.12
|
||||
|
||||
### Fixes
|
||||
|
||||
* 🐛 Fix `convert_underscores=False` for header Pydantic models. PR [#13515](https://github.com/fastapi/fastapi/pull/13515) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
### Docs
|
||||
|
||||
* 📝 Update `docs/en/docs/tutorial/middleware.md`. PR [#13444](https://github.com/fastapi/fastapi/pull/13444) by [@Rishat-F](https://github.com/Rishat-F).
|
||||
* 👥 Update FastAPI People - Experts. PR [#13493](https://github.com/fastapi/fastapi/pull/13493) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
### Translations
|
||||
|
||||
* 🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/metadata.md` page. PR [#13459](https://github.com/fastapi/fastapi/pull/13459) by [@valentinDruzhinin](https://github.com/valentinDruzhinin).
|
||||
* 🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/response-status-code.md` page. PR [#13462](https://github.com/fastapi/fastapi/pull/13462) by [@valentinDruzhinin](https://github.com/valentinDruzhinin).
|
||||
* 🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/cookie-param-models.md` page. PR [#13460](https://github.com/fastapi/fastapi/pull/13460) by [@valentinDruzhinin](https://github.com/valentinDruzhinin).
|
||||
* 🌐 Add Ukrainian translation for `docs/uk/docs/tutorial/header-param-models.md` page. PR [#13461](https://github.com/fastapi/fastapi/pull/13461) by [@valentinDruzhinin](https://github.com/valentinDruzhinin).
|
||||
* 🌐 Add Japanese translation for `docs/ja/docs/virtual-environments.md`. PR [#13304](https://github.com/fastapi/fastapi/pull/13304) by [@k94-ishi](https://github.com/k94-ishi).
|
||||
* 🌐 Add Korean translation for `docs/ko/docs/tutorial/security/oauth2-jwt.md`. PR [#13333](https://github.com/fastapi/fastapi/pull/13333) by [@yes0ng](https://github.com/yes0ng).
|
||||
* 🌐 Add Vietnamese translation for `docs/vi/docs/deployment/cloud.md`. PR [#13407](https://github.com/fastapi/fastapi/pull/13407) by [@ptt3199](https://github.com/ptt3199).
|
||||
|
||||
### Internal
|
||||
|
||||
* ⬆ Bump pydantic-ai from 0.0.15 to 0.0.30. PR [#13438](https://github.com/fastapi/fastapi/pull/13438) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
||||
* ⬆ Bump sqlmodel from 0.0.22 to 0.0.23. PR [#13437](https://github.com/fastapi/fastapi/pull/13437) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
||||
* ⬆ Bump black from 24.10.0 to 25.1.0. PR [#13436](https://github.com/fastapi/fastapi/pull/13436) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
||||
* ⬆ Bump ruff to 0.9.4. PR [#13299](https://github.com/fastapi/fastapi/pull/13299) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
||||
|
|
|
|||
|
|
@ -51,6 +51,22 @@ For example, if the client tries to send a `tool` header with a value of `plumbu
|
|||
}
|
||||
```
|
||||
|
||||
## Disable Convert Underscores
|
||||
|
||||
The same way as with regular header parameters, when you have underscore characters in the parameter names, they are **automatically converted to hyphens**.
|
||||
|
||||
For example, if you have a header parameter `save_data` in the code, the expected HTTP header will be `save-data`, and it will show up like that in the docs.
|
||||
|
||||
If for some reason you need to disable this automatic conversion, you can do it as well for Pydantic models for header parameters.
|
||||
|
||||
{* ../../docs_src/header_param_models/tutorial003_an_py310.py hl[19] *}
|
||||
|
||||
/// warning
|
||||
|
||||
Before setting `convert_underscores` to `False`, bear in mind that some HTTP proxies and servers disallow the usage of headers with underscores.
|
||||
|
||||
///
|
||||
|
||||
## Summary
|
||||
|
||||
You can use **Pydantic models** to declare **headers** in **FastAPI**. 😎
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ A "middleware" is a function that works with every **request** before it is proc
|
|||
|
||||
If you have dependencies with `yield`, the exit code will run *after* the middleware.
|
||||
|
||||
If there were any background tasks (documented later), they will run *after* all the middleware.
|
||||
If there were any background tasks (covered in the [Background Tasks](background-tasks.md){.internal-link target=_blank} section, you will see it later), they will run *after* all the middleware.
|
||||
|
||||
///
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ theme:
|
|||
name: material
|
||||
custom_dir: ../en/overrides
|
||||
palette:
|
||||
- media: "(prefers-color-scheme)"
|
||||
- media: (prefers-color-scheme)
|
||||
toggle:
|
||||
icon: material/lightbulb-auto
|
||||
name: Switch to light mode
|
||||
|
|
@ -27,7 +27,6 @@ theme:
|
|||
features:
|
||||
- content.code.annotate
|
||||
- content.code.copy
|
||||
# - content.code.select
|
||||
- content.footnote.tooltips
|
||||
- content.tabs.link
|
||||
- content.tooltips
|
||||
|
|
@ -35,7 +34,6 @@ theme:
|
|||
- navigation.indexes
|
||||
- navigation.instant
|
||||
- navigation.instant.prefetch
|
||||
# - navigation.instant.preview
|
||||
- navigation.instant.progress
|
||||
- navigation.path
|
||||
- navigation.tabs
|
||||
|
|
@ -46,7 +44,6 @@ theme:
|
|||
- search.share
|
||||
- search.suggest
|
||||
- toc.follow
|
||||
|
||||
icon:
|
||||
repo: fontawesome/brands/github-alt
|
||||
logo: img/icon-white.svg
|
||||
|
|
@ -55,11 +52,7 @@ theme:
|
|||
repo_name: fastapi/fastapi
|
||||
repo_url: https://github.com/fastapi/fastapi
|
||||
plugins:
|
||||
# Material for MkDocs
|
||||
search:
|
||||
# Configured in mkdocs.insiders.yml
|
||||
# social:
|
||||
# Other plugins
|
||||
search: null
|
||||
macros:
|
||||
include_yaml:
|
||||
- external_links: ../en/data/external_links.yml
|
||||
|
|
@ -103,7 +96,6 @@ plugins:
|
|||
signature_crossrefs: true
|
||||
show_symbol_type_heading: true
|
||||
show_symbol_type_toc: true
|
||||
|
||||
nav:
|
||||
- FastAPI: index.md
|
||||
- features.md
|
||||
|
|
@ -258,33 +250,27 @@ nav:
|
|||
- benchmarks.md
|
||||
- management.md
|
||||
- release-notes.md
|
||||
|
||||
markdown_extensions:
|
||||
# Python Markdown
|
||||
abbr:
|
||||
attr_list:
|
||||
footnotes:
|
||||
md_in_html:
|
||||
tables:
|
||||
abbr: null
|
||||
attr_list: null
|
||||
footnotes: null
|
||||
md_in_html: null
|
||||
tables: null
|
||||
toc:
|
||||
permalink: true
|
||||
|
||||
# Python Markdown Extensions
|
||||
pymdownx.betterem:
|
||||
pymdownx.caret:
|
||||
pymdownx.betterem: null
|
||||
pymdownx.caret: null
|
||||
pymdownx.highlight:
|
||||
line_spans: __span
|
||||
pymdownx.inlinehilite:
|
||||
pymdownx.keys:
|
||||
pymdownx.mark:
|
||||
pymdownx.inlinehilite: null
|
||||
pymdownx.keys: null
|
||||
pymdownx.mark: null
|
||||
pymdownx.superfences:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format
|
||||
pymdownx.tilde:
|
||||
|
||||
# pymdownx blocks
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
pymdownx.tilde: null
|
||||
pymdownx.blocks.admonition:
|
||||
types:
|
||||
- note
|
||||
|
|
@ -295,17 +281,13 @@ markdown_extensions:
|
|||
- tip
|
||||
- hint
|
||||
- warning
|
||||
# Custom types
|
||||
- info
|
||||
- check
|
||||
pymdownx.blocks.details:
|
||||
pymdownx.blocks.details: null
|
||||
pymdownx.blocks.tab:
|
||||
alternate_style: True
|
||||
|
||||
# Other extensions
|
||||
mdx_include:
|
||||
markdown_include_variants:
|
||||
|
||||
alternate_style: true
|
||||
mdx_include: null
|
||||
markdown_include_variants: null
|
||||
extra:
|
||||
analytics:
|
||||
provider: google
|
||||
|
|
@ -313,16 +295,14 @@ extra:
|
|||
feedback:
|
||||
title: Was this page helpful?
|
||||
ratings:
|
||||
- icon: material/emoticon-happy-outline
|
||||
name: This page was helpful
|
||||
data: 1
|
||||
note: >-
|
||||
Thanks for your feedback!
|
||||
- icon: material/emoticon-sad-outline
|
||||
name: This page could be improved
|
||||
data: 0
|
||||
note: >-
|
||||
Thanks for your feedback!
|
||||
- icon: material/emoticon-happy-outline
|
||||
name: This page was helpful
|
||||
data: 1
|
||||
note: Thanks for your feedback!
|
||||
- icon: material/emoticon-sad-outline
|
||||
name: This page could be improved
|
||||
data: 0
|
||||
note: Thanks for your feedback!
|
||||
social:
|
||||
- icon: fontawesome/brands/github-alt
|
||||
link: https://github.com/fastapi/fastapi
|
||||
|
|
@ -338,7 +318,6 @@ extra:
|
|||
link: https://medium.com/@tiangolo
|
||||
- icon: fontawesome/solid/globe
|
||||
link: https://tiangolo.com
|
||||
|
||||
alternate:
|
||||
- link: /
|
||||
name: en - English
|
||||
|
|
@ -390,14 +369,11 @@ extra:
|
|||
name: zh-hant - 繁體中文
|
||||
- link: /em/
|
||||
name: 😉
|
||||
|
||||
extra_css:
|
||||
- css/termynal.css
|
||||
- css/custom.css
|
||||
|
||||
extra_javascript:
|
||||
- js/termynal.js
|
||||
- js/custom.js
|
||||
|
||||
hooks:
|
||||
- ../../scripts/mkdocs_hooks.py
|
||||
|
|
|
|||
|
|
@ -0,0 +1,831 @@
|
|||
# 仮想環境
|
||||
|
||||
Pythonプロジェクトの作業では、**仮想環境**(または類似の仕組み)を使用し、プロジェクトごとにインストールするパッケージを分離するべきでしょう。
|
||||
|
||||
/// info | 情報
|
||||
|
||||
もし、仮想環境の概要や作成方法、使用方法について既にご存知なら、このセクションをスキップすることができます。🤓
|
||||
|
||||
///
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
**仮想環境**は、**環境変数**とは異なります。
|
||||
|
||||
**環境変数**は、プログラムが使用できるシステム内の変数です。
|
||||
|
||||
**仮想環境**は、ファイルをまとめたディレクトリのことです。
|
||||
|
||||
///
|
||||
|
||||
/// info | 情報
|
||||
このページでは、**仮想環境**の使用方法と、そのはたらきについて説明します。
|
||||
|
||||
もし**すべてを管理するツール**(Pythonのインストールも含む)を導入する準備ができているなら、<a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a> をお試しください。
|
||||
|
||||
///
|
||||
|
||||
## プロジェクトの作成
|
||||
|
||||
まず、プロジェクト用のディレクトリを作成します。
|
||||
|
||||
私は通常 home/user ディレクトリの中に `code` というディレクトリを用意していて、プロジェクトごとに1つのディレクトリをその中に作成しています。
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Go to the home directory
|
||||
$ cd
|
||||
// Create a directory for all your code projects
|
||||
$ mkdir code
|
||||
// Enter into that code directory
|
||||
$ cd code
|
||||
// Create a directory for this project
|
||||
$ mkdir awesome-project
|
||||
// Enter into that project directory
|
||||
$ cd awesome-project
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## 仮想環境の作成
|
||||
|
||||
Pythonプロジェクトでの**初めての**作業を開始する際には、**<abbr title="他の選択肢もありますが、これはシンプルなガイドラインです">プロジェクト内</abbr>**に仮想環境を作成してください。
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
これを行うのは、**プロジェクトごとに1回だけ**です。作業のたびに行う必要はありません。
|
||||
|
||||
///
|
||||
|
||||
//// tab | `venv`
|
||||
|
||||
仮想環境を作成するには、Pythonに付属している `venv` モジュールを使用できます。
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python -m venv .venv
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
/// details | このコマンドの意味
|
||||
|
||||
- `python` : `python` というプログラムを呼び出します
|
||||
- `-m` : モジュールをスクリプトとして呼び出します。どのモジュールを呼び出すのか、この次に指定します
|
||||
- `venv` : 通常Pythonに付随してインストールされる `venv`モジュールを使用します
|
||||
- `.venv` : 仮想環境を`.venv`という新しいディレクトリに作成します
|
||||
|
||||
///
|
||||
|
||||
////
|
||||
|
||||
//// tab | `uv`
|
||||
|
||||
もし <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> をインストール済みなら、仮想環境を作成するために `uv` を使うこともできます。
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uv venv
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
デフォルトでは、 `uv` は `.venv` というディレクトリに仮想環境を作成します。
|
||||
|
||||
ただし、追加の引数にディレクトリ名を与えてカスタマイズすることもできます。
|
||||
|
||||
///
|
||||
|
||||
////
|
||||
|
||||
このコマンドは `.venv` というディレクトリに新しい仮想環境を作成します。
|
||||
|
||||
/// details | `.venv` またはその他の名前
|
||||
|
||||
仮想環境を別のディレクトリに作成することも可能ですが、 `.venv` と名付けるのが一般的な慣習です。
|
||||
|
||||
///
|
||||
|
||||
## 仮想環境の有効化
|
||||
|
||||
実行されるPythonコマンドやインストールされるパッケージが新しく作成した仮想環境を使用するよう、その仮想環境を有効化しましょう。
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
そのプロジェクトの作業で**新しいターミナルセッション**を開始する際には、**毎回**有効化が必要です。
|
||||
|
||||
///
|
||||
|
||||
//// tab | Linux, macOS
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ source .venv/bin/activate
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows PowerShell
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ .venv\Scripts\Activate.ps1
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows Bash
|
||||
|
||||
もしWindowsでBashを使用している場合 (<a href="https://gitforwindows.org/" class="external-link" target="_blank">Git Bash</a>など):
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ source .venv/Scripts/activate
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
**新しいパッケージ**を仮想環境にインストールするときには、再度**有効化**してください。
|
||||
|
||||
こうすることで、そのパッケージがインストールした**ターミナル(<abbr title="command line interface">CLI</abbr>)プログラム**を使用する場合に、仮想環境内のものが確実に使われ、グローバル環境にインストールされている別のもの(おそらく必要なものとは異なるバージョン)を誤って使用することを防ぎます。
|
||||
|
||||
///
|
||||
|
||||
## 仮想環境が有効であることを確認する
|
||||
|
||||
仮想環境が有効である(前のコマンドが正常に機能した)ことを確認します。
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
これは**任意**ですが、すべてが期待通りに機能し、意図した仮想環境を使用していることを**確認する**良い方法です。
|
||||
|
||||
///
|
||||
|
||||
//// tab | Linux, macOS, Windows Bash
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ which python
|
||||
|
||||
/home/user/code/awesome-project/.venv/bin/python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
`.venv/bin/python` にある `python` バイナリが、プロジェクト(この場合は `awesome-project` )内に表示されていれば、正常に動作しています 🎉。
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows PowerShell
|
||||
|
||||
<div class="termy">
|
||||
|
||||
``` console
|
||||
$ Get-Command python
|
||||
|
||||
C:\Users\user\code\awesome-project\.venv\Scripts\python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
`.venv\Scripts\python` にある `python` バイナリが、プロジェクト(この場合は `awesome-project` )内に表示されていれば、正常に動作しています 🎉。
|
||||
|
||||
////
|
||||
|
||||
## `pip` をアップグレードする
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
もし <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> を使用している場合は、 `pip` の代わりに `uv` を使ってインストールを行うため、 `pip` をアップグレードする必要はありません 😎。
|
||||
|
||||
///
|
||||
|
||||
もしパッケージのインストールに `pip`(Pythonに標準で付属しています)を使用しているなら、 `pip` を最新バージョンに**アップグレード**しましょう。
|
||||
|
||||
パッケージのインストール中に発生する想定外のエラーの多くは、最初に `pip` をアップグレードしておくだけで解決されます。
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
通常、これは仮想環境を作成した直後に**一度だけ**実行します。
|
||||
|
||||
///
|
||||
|
||||
仮想環境が有効であることを(上で説明したコマンドで)確認し、アップグレードを実行しましょう:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python -m pip install --upgrade pip
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## `.gitignore` を追加する
|
||||
|
||||
**Git**を使用している場合(使用するべきでしょう)、 `.gitignore` ファイルを追加して、 `.venv` 内のあらゆるファイルをGitの管理対象から除外します。
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
もし <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> を使用して仮想環境を作成した場合、すでにこの作業は済んでいるので、この手順をスキップできます 😎。
|
||||
|
||||
///
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
これも、仮想環境を作成した直後に**一度だけ**実行します。
|
||||
|
||||
///
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ echo "*" > .venv/.gitignore
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
/// details | このコマンドの意味
|
||||
|
||||
- `echo "*"` : ターミナルに `*` というテキストを「表示」しようとします。(次の部分によってその動作が少し変わります)
|
||||
- `>` : `>` の左側のコマンドがターミナルに表示しようとする内容を、ターミナルには表示せず、 `>` の右側のファイルに書き込みます。
|
||||
- `.gitignore` : `*` を書き込むファイル名。
|
||||
|
||||
ここで、Gitにおける `*` は「すべて」を意味するので、このコマンドによって `.venv` ディレクトリ内のすべてがGitに無視されるようになります。
|
||||
|
||||
このコマンドは以下のテキストを持つ `.gitignore` ファイルを作成します:
|
||||
|
||||
```gitignore
|
||||
*
|
||||
```
|
||||
|
||||
///
|
||||
|
||||
## パッケージのインストール
|
||||
|
||||
仮想環境を有効化した後、その中でパッケージをインストールできます。
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
プロジェクトに必要なパッケージをインストールまたはアップグレードする場合、これを**一度**実行します。
|
||||
|
||||
もし新しいパッケージを追加したり、バージョンをアップグレードする必要がある場合は、もう**一度この手順を繰り返し**ます。
|
||||
|
||||
///
|
||||
|
||||
### パッケージを直接インストールする
|
||||
|
||||
急いでいて、プロジェクトのパッケージ要件を宣言するファイルを使いたくない場合、パッケージを直接インストールできます。
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
プログラムが必要とするパッケージとバージョンをファイル(例えば `requirements.txt` や `pyproject.toml` )に記載しておくのは、(とても)良い考えです。
|
||||
|
||||
///
|
||||
|
||||
//// tab | `pip`
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "fastapi[standard]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | `uv`
|
||||
|
||||
もし <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> を使用できるなら:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uv pip install "fastapi[standard]"
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
### `requirements.txt` からインストールする
|
||||
|
||||
もし `requirements.txt` があるなら、パッケージのインストールに使用できます。
|
||||
|
||||
//// tab | `pip`
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install -r requirements.txt
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | `uv`
|
||||
|
||||
もし <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> を使用できるなら:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uv pip install -r requirements.txt
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
/// details | `requirements.txt`
|
||||
|
||||
パッケージが記載された `requirements.txt` は以下のようになっています:
|
||||
|
||||
```requirements.txt
|
||||
fastapi[standard]==0.113.0
|
||||
pydantic==2.8.0
|
||||
```
|
||||
|
||||
///
|
||||
|
||||
## プログラムを実行する
|
||||
|
||||
仮想環境を有効化した後、プログラムを実行できます。この際、仮想環境内のPythonと、そこにインストールしたパッケージが使用されます。
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python main.py
|
||||
|
||||
Hello World
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## エディタの設定
|
||||
|
||||
プロジェクトではおそらくエディタを使用するでしょう。コード補完やインラインエラーの表示ができるように、作成した仮想環境をエディタでも使えるよう設定してください。(多くの場合、自動検出されます)
|
||||
|
||||
設定例:
|
||||
|
||||
* <a href="https://code.visualstudio.com/docs/python/environments#_select-and-activate-an-environment" class="external-link" target="_blank">VS Code</a>
|
||||
* <a href="https://www.jetbrains.com/help/pycharm/creating-virtual-environment.html" class="external-link" target="_blank">PyCharm</a>
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
この設定は通常、仮想環境を作成した際に**一度だけ**行います。
|
||||
|
||||
///
|
||||
|
||||
## 仮想環境の無効化
|
||||
|
||||
プロジェクトの作業が終了したら、その仮想環境を**無効化**できます。
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ deactivate
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
これにより、 `python` コマンドを実行しても、そのプロジェクト用(のパッケージがインストールされた)仮想環境から `python` プログラムを呼び出そうとはしなくなります。
|
||||
|
||||
## 作業準備完了
|
||||
|
||||
ここまでで、プロジェクトの作業を始める準備が整いました。
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
上記の内容を理解したいですか?
|
||||
|
||||
もしそうなら、以下を読み進めてください。👇🤓
|
||||
|
||||
///
|
||||
|
||||
## なぜ仮想環境?
|
||||
|
||||
FastAPIを使った作業をするには、 [Python](https://www.python.org/) のインストールが必要です。
|
||||
|
||||
それから、FastAPIや、使用したいその他の**パッケージ**を**インストール**する必要があります。
|
||||
|
||||
パッケージをインストールするには、通常、Python に付属する `pip` コマンド (または同様の代替コマンド) を使用します。
|
||||
|
||||
ただし、`pip` を直接使用すると、パッケージは**グローバルなPython環境**(OS全体にインストールされたPython環境)にインストールされます。
|
||||
|
||||
### 問題点
|
||||
|
||||
では、グローバルPython環境にパッケージをインストールすることの問題点は何でしょうか?
|
||||
|
||||
ある時点で、あなたは**異なるパッケージ**に依存する多くのプログラムを書くことになるでしょう。そして、これらの中には同じパッケージの**異なるバージョン**に依存するものも出てくるでしょう。😱
|
||||
|
||||
例えば、 `philosophers-stone` (賢者の石)というプロジェクトを作成するとします。このプログラムは **`harry` (ハリー)というパッケージのバージョン `1`**に依存しています。そのため、 `harry` (ハリー)をインストールする必要があります。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
stone(philosophers-stone) -->|requires| harry-1[harry v1]
|
||||
```
|
||||
|
||||
それから、 `prisoner-of-azkaban` (アズカバンの囚人)という別のプロジェクトを作成したとします。このプロジェクトも `harry` (ハリー)に依存していますが、**`harry` (ハリー)のバージョン `3`**が必要です。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
azkaban(prisoner-of-azkaban) --> |requires| harry-3[harry v3]
|
||||
```
|
||||
|
||||
しかし、ここで問題になるのは、もしローカルの**仮想環境**ではなくグローバル(環境)にパッケージをインストールするなら、 `harry` (ハリー)のどのバージョンをインストールするか選ばないといけないことです。
|
||||
|
||||
例えば、 `philosophers-stone` (賢者の石)を実行するには、まず `harry` (ハリー)のバージョン `1` をインストールする必要があります:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "harry==1"
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
これにより、`harry` (ハリー)バージョン1がグローバルなPython環境にインストールされます。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph global[global env]
|
||||
harry-1[harry v1]
|
||||
end
|
||||
subgraph stone-project[philosophers-stone project]
|
||||
stone(philosophers-stone) -->|requires| harry-1
|
||||
end
|
||||
```
|
||||
|
||||
しかし、 `prisoner-of-azkaban` (アズカバンの囚人)を実行したい場合は、`harry` (ハリー)のバージョン `1` をアンインストールし、`harry` (ハリー)のバージョン `3` をインストールし直す必要があります。(あるいは、単に`harry` (ハリー)のバージョン `3` をインストールすることで、自動的にバージョン `1` がアンインストールされます)
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "harry==3"
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
このようにして、グローバル環境への `harry` (ハリー)のバージョン `3` のインストールが完了します。
|
||||
|
||||
それから、 `philosophers-stone` (賢者の石)を再び実行しようとすると、このプログラムは `harry` (ハリー)のバージョン `1` が必要なため、**動作しなくなる**可能性があります。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph global[global env]
|
||||
harry-1[<strike>harry v1</strike>]
|
||||
style harry-1 fill:#ccc,stroke-dasharray: 5 5
|
||||
harry-3[harry v3]
|
||||
end
|
||||
subgraph stone-project[philosophers-stone project]
|
||||
stone(philosophers-stone) -.-x|⛔️| harry-1
|
||||
end
|
||||
subgraph azkaban-project[prisoner-of-azkaban project]
|
||||
azkaban(prisoner-of-azkaban) --> |requires| harry-3
|
||||
end
|
||||
```
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
Pythonのパッケージでは、**新しいバージョン**で**互換性を損なう変更を避ける**よう努めるのが一般的ですが、それでも注意が必要です。すべてが正常に動作することをテストで確認してから、意図的に指定して新しいバージョンをインストールするのが良いでしょう。
|
||||
|
||||
///
|
||||
|
||||
あなたのすべての**プロジェクトが依存している**、**多数の**他の**パッケージ**が上記の問題を抱えていると想像してください。これは管理が非常に困難です。そして、**互換性のないバージョン**のパッケージを使ってプロジェクトを実行し、なぜ動作しないのか分からなくなるでしょう。
|
||||
|
||||
また、使用しているOS(Linux、Windows、macOS など)によっては、Pythonがすでにインストールされていることがあります。この場合、特定のバージョンのパッケージが**OSの動作に必要である**ことがあります。グローバル環境にパッケージをインストールすると、OSに付属するプログラムを**壊してしまう**可能性があります。
|
||||
|
||||
## パッケージのインストール先
|
||||
|
||||
Pythonをインストールしたとき、ファイルを含んだいくつかのディレクトリが作成されます。
|
||||
|
||||
これらの中には、インストールされたパッケージを保存するためのものもあります。
|
||||
|
||||
以下のコマンドを実行したとき:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Don't run this now, it's just an example 🤓
|
||||
$ pip install "fastapi[standard]"
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
FastAPIのコードを含む圧縮ファイルが、通常は [PyPI](https://pypi.org/project/fastapi/) からダウンロードされます。
|
||||
|
||||
また、FastAPIが依存する他のパッケージも**ダウンロード**されます。
|
||||
|
||||
それから、これらのファイルは**解凍**され、コンピュータのあるディレクトリに配置されます。
|
||||
|
||||
デフォルトでは、これらのファイルはPythonのインストール時に作成されるディレクトリ、つまり**グローバル環境**に配置されます。
|
||||
|
||||
## 仮想環境とは
|
||||
|
||||
すべてのパッケージをグローバル環境に配置することによって生じる問題の解決策は、作業する**プロジェクトごとの仮想環境**を使用することです。
|
||||
|
||||
仮想環境は**ディレクトリ**であり、グローバル環境と非常に似ていて、一つのプロジェクトで使う特定のパッケージ群をインストールできる場所です。
|
||||
|
||||
このようにして、それぞれのプロジェクトが独自の仮想環境(`.venv` ディレクトリ)に独自のパッケージ群を持つことができます。
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph stone-project[philosophers-stone project]
|
||||
stone(philosophers-stone) --->|requires| harry-1
|
||||
subgraph venv1[.venv]
|
||||
harry-1[harry v1]
|
||||
end
|
||||
end
|
||||
subgraph azkaban-project[prisoner-of-azkaban project]
|
||||
azkaban(prisoner-of-azkaban) --->|requires| harry-3
|
||||
subgraph venv2[.venv]
|
||||
harry-3[harry v3]
|
||||
end
|
||||
end
|
||||
stone-project ~~~ azkaban-project
|
||||
```
|
||||
|
||||
## 仮想環境の有効化とは
|
||||
|
||||
仮想環境を有効にしたとき、例えば次のコマンドを実行した場合を考えます:
|
||||
|
||||
//// tab | Linux, macOS
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ source .venv/bin/activate
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows PowerShell
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ .venv\Scripts\Activate.ps1
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows Bash
|
||||
|
||||
あるいは、WindowsでBashを使用している場合 (<a href="https://gitforwindows.org/" class="external-link" target="_blank">Git Bash</a>など):
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ source .venv/Scripts/activate
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
これによって、いくつかの [環境変数](environment-variables.md){.internal-link target=_blank} が作成・修正され、次に実行されるコマンドで使用できるようになります。
|
||||
|
||||
これらの環境変数のひとつに、 `PATH` 変数があります。
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
`PATH` 変数についての詳細は [環境変数](environment-variables.md#path環境変数){.internal-link target=_blank} を参照してください。
|
||||
|
||||
///
|
||||
|
||||
仮想環境を有効にすると、その仮想環境のパス `.venv/bin` (LinuxとmacOS)、あるいは `.venv\Scripts` (Windows)が `PATH` 変数に追加されます。
|
||||
|
||||
その環境を有効にする前の `PATH` 変数が次のようになっているとします。
|
||||
|
||||
//// tab | Linux, macOS
|
||||
|
||||
```plaintext
|
||||
/usr/bin:/bin:/usr/sbin:/sbin
|
||||
```
|
||||
|
||||
これは、OSが以下のディレクトリ中でプログラムを探すことを意味します:
|
||||
|
||||
* `/usr/bin`
|
||||
* `/bin`
|
||||
* `/usr/sbin`
|
||||
* `/sbin`
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows
|
||||
|
||||
```plaintext
|
||||
C:\Windows\System32
|
||||
```
|
||||
|
||||
これは、OSが以下のディレクトリ中でプログラムを探すことを意味します:
|
||||
|
||||
* `C:\Windows\System32`
|
||||
|
||||
////
|
||||
|
||||
仮想環境を有効にすると、 `PATH` 変数は次のようになります。
|
||||
|
||||
//// tab | Linux, macOS
|
||||
|
||||
```plaintext
|
||||
/home/user/code/awesome-project/.venv/bin:/usr/bin:/bin:/usr/sbin:/sbin
|
||||
```
|
||||
|
||||
これは、OSが他のディレクトリを探すより前に、最初に以下のディレクトリ中でプログラムを探し始めることを意味します:
|
||||
|
||||
```plaintext
|
||||
/home/user/code/awesome-project/.venv/bin
|
||||
```
|
||||
|
||||
そのため、ターミナルで `python` と入力した際に、OSはPythonプログラムを以下のパスで発見し、使用します。
|
||||
|
||||
```plaintext
|
||||
/home/user/code/awesome-project/.venv/bin/python
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows
|
||||
|
||||
```plaintext
|
||||
C:\Users\user\code\awesome-project\.venv\Scripts;C:\Windows\System32
|
||||
```
|
||||
|
||||
これは、OSが他のディレクトリを探すより前に、最初に以下のディレクトリ中でプログラムを探し始めることを意味します:
|
||||
|
||||
```plaintext
|
||||
C:\Users\user\code\awesome-project\.venv\Scripts
|
||||
```
|
||||
|
||||
そのため、ターミナルで `python` と入力した際に、OSはPythonプログラムを以下のパスで発見し、使用します。
|
||||
|
||||
```plaintext
|
||||
C:\Users\user\code\awesome-project\.venv\Scripts\python
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
重要な点は、仮想環境のパスを `PATH` 変数の**先頭**に配置することです。OSは利用可能な他のPythonを見つけるより**前に**、この仮想環境のPythonを見つけるようになります。このようにして、 `python` を実行したときに、他の `python` (例えばグローバル環境の `python` )ではなく、**その仮想環境の**Pythonを使用するようになります。
|
||||
|
||||
仮想環境を有効にして変更されることは他にもありますが、これが最も重要な変更のひとつです。
|
||||
|
||||
## 仮想環境の確認
|
||||
|
||||
仮想環境が有効かどうか、例えば次のように確認できます。:
|
||||
|
||||
//// tab | Linux, macOS, Windows Bash
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ which python
|
||||
|
||||
/home/user/code/awesome-project/.venv/bin/python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Windows PowerShell
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ Get-Command python
|
||||
|
||||
C:\Users\user\code\awesome-project\.venv\Scripts\python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
これは、使用される `python` プログラムが**その仮想環境の**ものであることを意味します。
|
||||
|
||||
LinuxやmacOSでは `which` を、Windows PowerShellでは `Get-Command` を使用します。
|
||||
|
||||
このコマンドの動作は、 `PATH`変数に設定された**それぞれのパスを順に**確認していき、呼ばれている `python` プログラムを探します。そして、見つかり次第そのプログラムへの**パスを表示します**。
|
||||
|
||||
最も重要なことは、 `python` が呼ばれたときに、まさにこのコマンドで確認した "`python`" が実行されることです。
|
||||
|
||||
こうして、自分が想定通りの仮想環境にいるかを確認できます。
|
||||
|
||||
/// tip | 豆知識
|
||||
|
||||
ある仮想環境を有効にし、そのPythonを使用したまま**他のプロジェクトに移動して**しまうことは簡単に起こり得ます。
|
||||
|
||||
そして、その第二のプロジェクトは動作しないでしょう。なぜなら別のプロジェクトの仮想環境の**誤ったPython**を使用しているからです。
|
||||
|
||||
そのため、どの `python` が使用されているのか確認できることは役立ちます。🤓
|
||||
|
||||
///
|
||||
|
||||
## なぜ仮想環境を無効化するのか
|
||||
|
||||
例えば、`philosophers-stone` (賢者の石)というプロジェクトで作業をしていて、**その仮想環境を有効にし**、必要なパッケージをインストールしてその環境内で作業を進めているとします。
|
||||
|
||||
それから、**別のプロジェクト**、 `prisoner-of-azkaban` (アズカバンの囚人)に取り掛かろうとします。
|
||||
|
||||
そのプロジェクトディレクトリへ移動します:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ cd ~/code/prisoner-of-azkaban
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
もし `philosophers-stone` (賢者の石)の仮想環境を無効化していないと、`python` を実行したとき、 ターミナルは `philosophers-stone` (賢者の石)のPythonを使用しようとします。
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ cd ~/code/prisoner-of-azkaban
|
||||
|
||||
$ python main.py
|
||||
|
||||
// Error importing sirius, it's not installed 😱
|
||||
Traceback (most recent call last):
|
||||
File "main.py", line 1, in <module>
|
||||
import sirius
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
しかし、その仮想環境を無効化し、 `prisoner-of-azkaban` (アズカバンの囚人)のための新しい仮想環境を有効にすれば、 `python` を実行したときに `prisoner-of-azkaban` (アズカバンの囚人)の仮想環境の Python が使用されるようになります。
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ cd ~/code/prisoner-of-azkaban
|
||||
|
||||
// You don't need to be in the old directory to deactivate, you can do it wherever you are, even after going to the other project 😎
|
||||
$ deactivate
|
||||
|
||||
// Activate the virtual environment in prisoner-of-azkaban/.venv 🚀
|
||||
$ source .venv/bin/activate
|
||||
|
||||
// Now when you run python, it will find the package sirius installed in this virtual environment ✨
|
||||
$ python main.py
|
||||
|
||||
I solemnly swear 🐺
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## 代替手段
|
||||
|
||||
これは、あらゆる仕組みを**根本から**学ぶためのシンプルな入門ガイドです。
|
||||
|
||||
仮想環境、パッケージの依存関係(requirements)、プロジェクトの管理には、多くの**代替手段**があります。
|
||||
|
||||
準備が整い、パッケージの依存関係、仮想環境など**プロジェクト全体の管理**ツールを使いたいと考えたら、<a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a> を試してみることをおすすめします。
|
||||
|
||||
`uv` では以下のような多くのことができます:
|
||||
|
||||
* 異なるバージョンも含めた**Python のインストール**
|
||||
* プロジェクトごとの**仮想環境**の管理
|
||||
* **パッケージ**のインストール
|
||||
* プロジェクトのパッケージの**依存関係やバージョン**の管理
|
||||
* パッケージとそのバージョンの、依存関係を含めた**厳密な**組み合わせを保持し、これによって、本番環境で、開発環境と全く同じようにプロジェクトを実行できる(これは**locking**と呼ばれます)
|
||||
* その他のさまざまな機能
|
||||
|
||||
## まとめ
|
||||
|
||||
ここまで読みすべて理解したなら、世間の多くの開発者と比べて、仮想環境について**あなたはより多くのことを知っています**。🤓
|
||||
|
||||
これらの詳細を知ることは、将来、複雑に見える何かのデバッグにきっと役立つでしょう。しかし、その頃には、あなたは**そのすべての動作を根本から**理解しているでしょう。😎
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
# Модели Header-параметров
|
||||
|
||||
Если у вас есть группа связанных **header-параметров**, то вы можете объединить их в одну **Pydantic-модель**.
|
||||
|
||||
Это позволит вам **переиспользовать модель** в **разных местах**, а также задать валидацию и метаданные сразу для всех параметров. 😎
|
||||
|
||||
/// note | Заметка
|
||||
|
||||
Этот функционал доступен в FastAPI начиная с версии `0.115.0`. 🤓
|
||||
|
||||
///
|
||||
|
||||
## Header-параметры в виде Pydantic-модели
|
||||
|
||||
Объявите нужные **header-параметры** в **Pydantic-модели** и затем аннотируйте параметр как `Header`:
|
||||
|
||||
{* ../../docs_src/header_param_models/tutorial001_an_py310.py hl[9:14,18] *}
|
||||
|
||||
**FastAPI** **извлечёт** данные для **каждого поля** из **заголовков** запроса и выдаст заданную вами Pydantic-модель.
|
||||
|
||||
## Проверьте документацию
|
||||
|
||||
Вы можете посмотреть нужные header-параметры в графическом интерфейсе сгенерированной документации по пути `/docs`:
|
||||
|
||||
<div class="screenshot">
|
||||
<img src="/img/tutorial/header-param-models/image01.png">
|
||||
</div>
|
||||
|
||||
## Как запретить дополнительные заголовки
|
||||
|
||||
В некоторых случаях (не особо часто встречающихся) вам может понадобиться **ограничить** заголовки, которые вы хотите получать.
|
||||
|
||||
Вы можете использовать возможности конфигурации Pydantic-модели для того, чтобы запретить (`forbid`) любые дополнительные (`extra`) поля:
|
||||
|
||||
{* ../../docs_src/header_param_models/tutorial002_an_py310.py hl[10] *}
|
||||
|
||||
Если клиент попробует отправить **дополнительные заголовки**, то в ответ он получит **ошибку**.
|
||||
|
||||
Например, если клиент попытается отправить заголовок `tool` со значением `plumbus`, то в ответ он получит ошибку, сообщающую ему, что header-параметр `tool` не разрешен:
|
||||
|
||||
```json
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "extra_forbidden",
|
||||
"loc": ["header", "tool"],
|
||||
"msg": "Extra inputs are not permitted",
|
||||
"input": "plumbus",
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Как отключить автоматическое преобразование подчеркиваний
|
||||
|
||||
Как и в случае с обычными заголовками, если у вас в именах параметров имеются символы подчеркивания, они **автоматически преобразовываются в дефис**.
|
||||
|
||||
Например, если в коде есть header-параметр `save_data`, то ожидаемый HTTP-заголовок будет `save-data` и именно так он будет отображаться в документации.
|
||||
|
||||
Если по каким-то причинам вам нужно отключить данное автоматическое преобразование, это можно сделать и для Pydantic-моделей для header-параметров.
|
||||
|
||||
{* ../../docs_src/header_param_models/tutorial003_an_py310.py hl[19] *}
|
||||
|
||||
/// warning | Внимание
|
||||
|
||||
Перед тем как устанавливать для параметра `convert_underscores` значение `False`, имейте в виду, что некоторые HTTP-прокси и серверы не разрешают использовать заголовки с символами подчеркивания.
|
||||
|
||||
///
|
||||
|
||||
## Резюме
|
||||
|
||||
Вы можете использовать **Pydantic-модели** для объявления **header-параметров** в **FastAPI**. 😎
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
# Моделі для Cookie-параметрів
|
||||
|
||||
Якщо у Вас є група **cookies** параметрів, які пов'язані між собою, Ви можете створити **Pydantic-модель**, щоб оголосити їх. 🍪
|
||||
|
||||
Це дозволить Вам повторно **використовувати модель** у **різних місцях**, а також оголосити валідацію та метадані для всіх параметрів одночасно. 😎
|
||||
|
||||
/// note | Нотатки
|
||||
|
||||
Це підтримується з версії FastAPI `0.115.0`. 🤓
|
||||
|
||||
///
|
||||
|
||||
/// tip | Порада
|
||||
|
||||
Ця ж техніка застосовується до `Query`, `Cookie`, та `Header`. 😎
|
||||
|
||||
///
|
||||
|
||||
## Cookie з Pydantic-моделлю
|
||||
|
||||
Оголосіть **cookie-параметри**, які Вам потрібні, у **Pydantic-моделі**, а потім оголосіть параметр як `Cookie`:
|
||||
|
||||
{* ../../docs_src/cookie_param_models/tutorial001_an_py310.py hl[9:12,16] *}
|
||||
|
||||
**FastAPI** буде **витягувати** дані для **кожного поля** з **cookie** параметрів, отриманих у запиті, і передавати Вам Pydantic-модель, яку Ви визначили.
|
||||
|
||||
## Перевірка у документації
|
||||
|
||||
Ви можете побачити визначені cookie в інтерфейсі документації за адресою `/docs`:
|
||||
|
||||
<div class="screenshot">
|
||||
<img src="/img/tutorial/cookie-param-models/image01.png">
|
||||
</div>
|
||||
|
||||
/// info | Інформація
|
||||
|
||||
Майте на увазі, що оскільки **браузери обробляють cookie** особливим чином і "за лаштунками", вони **не** дозволяють **JavaScript** легко з ними працювати.
|
||||
|
||||
Якщо Ви зайдете до **інтерфейсу документації API** за адресою `/docs`, Ви зможете побачити **документацію** для cookie у Ваших **операціях шляху**.
|
||||
|
||||
Але навіть якщо Ви заповните дані й натиснете "Execute", оскільки інтерфейс документації працює з **JavaScript**, cookie не будуть відправлені, і Ви побачите **помилку**, ніби Ви не ввели жодних значень.
|
||||
|
||||
///
|
||||
|
||||
## Заборона додаткових cookie
|
||||
|
||||
У деяких спеціальних випадках (ймовірно, не дуже поширених) Ви можете захотіти **обмежити** список cookie, які хочете отримувати.
|
||||
|
||||
Ваша API тепер має можливість контролювати власну <abbr title="Це жарт, якщо що. Це не має нічого спільного зі згодою на використання cookie, але це кумедно, що навіть API тепер може відхиляти бідні cookie. Ловіть печиво. 🍪">згоду на cookie</abbr>. 🤪🍪
|
||||
|
||||
Ви можете використовувати налаштування моделі Pydantic, щоб `заборонити` будь-які `додаткові` поля:
|
||||
|
||||
{* ../../docs_src/cookie_param_models/tutorial002_an_py39.py hl[10] *}
|
||||
|
||||
Якщо клієнт спробує надіслати якісь **додаткові cookie**, він отримає відповідь з **помилкою**.
|
||||
|
||||
Бідні банери cookie, які так старанно намагаються отримати Вашу згоду, щоб <abbr title="Це ще один жарт. Не звертайте уваги. Візьміть каву для свого печива. ☕">API її відхилила</abbr>. 🍪
|
||||
|
||||
Наприклад, якщо клієнт спробує надіслати cookie `santa_tracker` зі значенням `good-list-please`, він отримає відповідь з помилкою, яка повідомить, що <abbr title="Санта не схвалює відсутність cookie. 🎅 Гаразд, більше жартів не буде.">cookie `santa_tracker` не дозволено</abbr>:
|
||||
|
||||
```json
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "extra_forbidden",
|
||||
"loc": ["cookie", "santa_tracker"],
|
||||
"msg": "Extra inputs are not permitted",
|
||||
"input": "good-list-please",
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Підсумок
|
||||
|
||||
Ви можете використовувати **Pydantic-моделі** для оголошення <abbr title="Отримайте останнє печиво перед тим, як піти. 🍪">cookie</abbr> у FastAPI. 😎
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
# Моделі Параметрів Заголовків
|
||||
|
||||
Якщо у Вас є група пов’язаних параметрів заголовків, Ви можете створити **Pydantic модель** для їх оголошення.
|
||||
|
||||
Це дозволить Вам повторно **використовувати модель** в **різних місцях**, а також оголосити валідації та метадані для всіх параметрів одночасно. 😎
|
||||
|
||||
/// note | Нотатки
|
||||
|
||||
Ця можливість підтримується починаючи з версії FastAPI `0.115.0`. 🤓
|
||||
|
||||
///
|
||||
|
||||
## Параметри Заголовків з Використанням Pydantic Model
|
||||
|
||||
Оголосіть потрібні **параметри заголовків** у **Pydantic моделі**, а потім оголосіть параметр як `Header`:
|
||||
|
||||
{* ../../docs_src/header_param_models/tutorial001_an_py310.py hl[9:14,18] *}
|
||||
|
||||
FastAPI буде витягувати дані для кожного поля з заголовків у запиті та передавати їх у створену Вами Pydantic модель.
|
||||
|
||||
**FastAPI** буде **витягувати** дані для **кожного поля** з **заголовків** у запиті та передавати їх у створену Вами Pydantic модель.
|
||||
|
||||
## Перевірка в Документації
|
||||
|
||||
Ви можете побачити необхідні заголовки в інтерфейсі документації за адресою `/docs`:
|
||||
|
||||
<div class="screenshot">
|
||||
<img src="/img/tutorial/header-param-models/image01.png">
|
||||
</div>
|
||||
|
||||
## Заборона Додаткових Заголовків
|
||||
|
||||
У деяких особливих випадках (ймовірно, не дуже поширених) Ви можете захотіти **обмежити** заголовки, які хочете отримати.
|
||||
|
||||
Ви можете використати конфігурацію моделі Pydantic, щоб `заборонити` будь-які `додаткові` поля:
|
||||
|
||||
{* ../../docs_src/header_param_models/tutorial002_an_py310.py hl[10] *}
|
||||
|
||||
Якщо клієнт спробує надіслати **додаткові заголовки**, він отримає **помилку** у відповіді.
|
||||
|
||||
Наприклад, якщо клієнт спробує надіслати заголовок `tool` зі значенням `plumbus`, він отримає **помилку** з повідомленням про те, що параметр заголовка `tool` не дозволений:
|
||||
|
||||
```json
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"type": "extra_forbidden",
|
||||
"loc": ["header", "tool"],
|
||||
"msg": "Extra inputs are not permitted",
|
||||
"input": "plumbus",
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Підсумок
|
||||
|
||||
Ви можете використовувати **Pydantic моделі** для оголошення **заголовків** у **FastAPI**. 😎
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
# Метадані та URL-адреси документації
|
||||
|
||||
Ви можете налаштувати кілька конфігурацій метаданих у Вашому додатку **FastAPI**.
|
||||
|
||||
## Метадані для API
|
||||
|
||||
Ви можете встановити такі поля, які використовуються в специфікації OpenAPI та в автоматично згенерованих інтерфейсах документації API:
|
||||
|
||||
| Параметр | Тип | Опис |
|
||||
|------------|------|-------------|
|
||||
| `title` | `str` | Назва API. |
|
||||
| `summary` | `str` | Короткий опис API. <small>Доступно з OpenAPI 3.1.0, FastAPI 0.99.0.</small> |
|
||||
| `description` | `str` | Більш детальний опис API. Може використовувати Markdown. |
|
||||
| `version` | `string` | Версія API. Це версія Вашого додатка, а не OpenAPI. Наприклад, `2.5.0`. |
|
||||
| `terms_of_service` | `str` | URL до умов використання API. Якщо вказано, має бути у форматі URL. |
|
||||
| `contact` | `dict` | Інформація для контакту з API. Може містити кілька полів. <details><summary><code>contact</code> поля</summary><table><thead><tr><th>Параметр</th><th>Тип</th><th>Опис</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td>Ім'я контактної особи або організації.</td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>URL з інформацією для контакту. Повинен бути у форматі URL.</td></tr><tr><td><code>email</code></td><td><code>str</code></td><td>Email контактної особи або організації. Повинен бути у форматі електронної пошти.</td></tr></tbody></table></details> |
|
||||
| `license_info` | `dict` | Інформація про ліцензію для API. Може містити кілька полів. <details><summary><code>license_info</code> поля</summary><table><thead><tr><th>Параметр</th><th>Тип</th><th>Опис</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td><strong>ОБОВ'ЯЗКОВО</strong> (якщо встановлено <code>license_info</code>). Назва ліцензії для API.</td></tr><tr><td><code>identifier</code></td><td><code>str</code></td><td>Ліцензійний вираз за <a href="https://spdx.org/licenses/" class="external-link" target="_blank">SPDX</a> для API. Поле <code>identifier</code> взаємовиключне з полем <code>url</code>. <small>Доступно з OpenAPI 3.1.0, FastAPI 0.99.0.</small></td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>URL до ліцензії, яка використовується для API. Повинен бути у форматі URL.</td></tr></tbody></table></details> |
|
||||
|
||||
Ви можете налаштувати їх наступним чином:
|
||||
|
||||
{* ../../docs_src/metadata/tutorial001.py hl[3:16, 19:32] *}
|
||||
|
||||
/// tip | Підказка
|
||||
|
||||
У полі `description` можна використовувати Markdown, і він буде відображатися у результаті.
|
||||
|
||||
///
|
||||
|
||||
З цією конфігурацією автоматична документація API виглядатиме так:
|
||||
|
||||
<img src="/img/tutorial/metadata/image01.png">
|
||||
|
||||
## Ідентифікатор ліцензії
|
||||
|
||||
З початку використання OpenAPI 3.1.0 та FastAPI 0.99.0 Ви також можете налаштувати `license_info` за допомогою `identifier` замість `url`.
|
||||
|
||||
Наприклад:
|
||||
|
||||
{* ../../docs_src/metadata/tutorial001_1.py hl[31] *}
|
||||
|
||||
## Метадані для тегів
|
||||
|
||||
Ви також можете додати додаткові метадані для різних тегів, які використовуються для групування операцій шляхів, за допомогою параметра `openapi_tags`.
|
||||
|
||||
Він приймає список, який містить один словник для кожного тега.
|
||||
|
||||
Кожен словник може містити:
|
||||
|
||||
* `name` (**обов'язково**): `str` з тією ж назвою тегу, яку Ви використовуєте у параметрі `tags` у Ваших *операціях шляху* та `APIRouter`s.
|
||||
* `description`: `str` з коротким описом тегу. Може містити Markdown і буде відображено в інтерфейсі документації.
|
||||
* `externalDocs`: `dict` який описує зовнішню документацію з такими полями:
|
||||
* `description`: `str` з коротким описом зовнішньої документації.
|
||||
* `url` (**обов'язково**): `str`з URL-адресою зовнішньої документації.
|
||||
|
||||
### Створення метаданих для тегів
|
||||
|
||||
Спробуймо це на прикладі з тегами для `users` та `items`.
|
||||
|
||||
Створіть метадані для своїх тегів і передайте їх у параметр `openapi_tags`:
|
||||
|
||||
{* ../../docs_src/metadata/tutorial004.py hl[3:16,18] *}
|
||||
|
||||
Зверніть увагу, що в описах можна використовувати Markdown, наприклад, "login" буде показано жирним шрифтом (**login**), а "fancy" буде показано курсивом (_fancy_).
|
||||
|
||||
/// tip | Порада
|
||||
|
||||
Не обов'язково додавати метадані для всіх тегів, які Ви використовуєте.
|
||||
|
||||
///
|
||||
|
||||
### Використання тегів
|
||||
|
||||
Використовуйте параметр `tags` зі своїми *операціями шляху* (і `APIRouter`) для призначення їх до різних тегів:
|
||||
|
||||
{* ../../docs_src/metadata/tutorial004.py hl[21,26] *}
|
||||
|
||||
/// info | Інформація
|
||||
|
||||
Детальніше про теги читайте в розділі [Конфігурація шляхів операцій](path-operation-configuration.md#tags){.internal-link target=_blank}.
|
||||
|
||||
///
|
||||
|
||||
### Перевірка документації
|
||||
|
||||
Якщо Ви зараз перевірите документацію, вона покаже всі додаткові метадані:
|
||||
|
||||
<img src="/img/tutorial/metadata/image02.png">
|
||||
|
||||
### Порядок тегів
|
||||
|
||||
Порядок кожного словника метаданих тегу також визначає порядок відображення в інтерфейсі документації.
|
||||
|
||||
Наприклад, хоча `users` мав би йти після `items` в алфавітному порядку, він відображається перед ними, оскільки ми додали його метадані як перший словник у списку.
|
||||
|
||||
## URL для OpenAPI
|
||||
|
||||
За замовчуванням схема OpenAPI надається за адресою `/openapi.json`.
|
||||
|
||||
Але Ви можете налаштувати це за допомогою параметра `openapi_url`.
|
||||
|
||||
Наприклад, щоб налаштувати його на `/api/v1/openapi.json`:
|
||||
|
||||
{* ../../docs_src/metadata/tutorial002.py hl[3] *}
|
||||
|
||||
Якщо Ви хочете повністю вимкнути схему OpenAPI, Ви можете встановити `openapi_url=None`, це також вимкне інтерфейси документації, які її використовують.
|
||||
|
||||
## URL-адреси документації
|
||||
|
||||
Ви можете налаштувати два інтерфейси користувача для документації, які включені:
|
||||
|
||||
* **Swagger UI**: доступний за адресою `/docs`.
|
||||
* Ви можете змінити його URL за допомогою параметра `docs_url`.
|
||||
* Ви можете вимкнути його, встановивши `docs_url=None`.
|
||||
* **ReDoc**: доступний за адресою `/redoc`.
|
||||
* Ви можете змінити його URL за допомогою параметра `redoc_url`.
|
||||
* Ви можете вимкнути його, встановивши `redoc_url=None`.
|
||||
|
||||
Наприклад, щоб налаштувати Swagger UI на `/documentation` і вимкнути ReDoc:
|
||||
|
||||
{* ../../docs_src/metadata/tutorial003.py hl[3] *}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
# Статус коди Відповідей
|
||||
|
||||
Так само як Ви можете вказати модель відповіді, Ви також можете оголосити HTTP код статусу для відповіді за допомогою параметра `status_code` в будь-якій з *операцій шляху*:
|
||||
|
||||
* `@app.get()`
|
||||
* `@app.post()`
|
||||
* `@app.put()`
|
||||
* `@app.delete()`
|
||||
* тощо.
|
||||
|
||||
{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
|
||||
|
||||
/// note | Нотатка
|
||||
|
||||
Зверніть увагу, що `status_code` є параметром методу "декоратора" (`get`, `post` і т.д.), а не Вашої *функції операції шляху*, як усі інші параметри та тіло запиту.
|
||||
|
||||
///
|
||||
|
||||
Параметр `status_code` приймає число, яке відповідає HTTP коду статусу.
|
||||
|
||||
/// info | Інформація
|
||||
`status_code` також може отримувати значення з `IntEnum`, наприклад, з Python <a href="https://docs.python.org/3/library/http.html#http.HTTPStatus" class="external-link" target="_blank">`http.HTTPStatus`</a>.
|
||||
|
||||
///
|
||||
|
||||
Він буде:
|
||||
|
||||
* Повертати вказаний код статусу у відповіді.
|
||||
* Документувати його як такий у схемі OpenAPI (і, таким чином, в інтерфейсі користувача):
|
||||
|
||||
<img src="/img/tutorial/response-status-code/image01.png">
|
||||
|
||||
/// note | Нотатка
|
||||
|
||||
Деякі коди відповіді (див. наступний розділ) вказують, що відповідь не має тіла.
|
||||
|
||||
FastAPI знає про це і створить OpenAPI документацію, яка вказує, що тіла відповіді немає.
|
||||
|
||||
///
|
||||
|
||||
## Про HTTP статус коди
|
||||
|
||||
/// note | Нотатка
|
||||
|
||||
Якщо Ви вже знаєте, що таке HTTP коди статусу, переходьте до наступного розділу.
|
||||
|
||||
///
|
||||
|
||||
В HTTP Ви надсилаєте числовий код статусу з 3 цифр як частину відповіді.
|
||||
|
||||
Ці коди статусу мають пов’язану назву для їх розпізнавання, але найважливішою частиною є саме число.
|
||||
|
||||
Коротко:
|
||||
|
||||
* **`100 - 199`** "Інформаційні" відповіді. Ви рідко використовуєте їх напряму. Відповіді з такими кодами не можуть мати тіла.
|
||||
* **`200 - 299`** "Успішні" відповіді. Це ті, які Ви використовуватимете найчастіше.
|
||||
* `200` - код за замовчуванням, який означає, що все пройшло "OK".
|
||||
* Інший приклад – `201`, "Created" (створено). Його зазвичай використовують після створення нового запису в базі даних.
|
||||
* Особливий випадок – `204`, "No Content" (немає вмісту). Ця відповідь використовується, коли немає даних для повернення клієнту, тому відповідь не повинна мати тіла.
|
||||
* **`300 - 399`** "Перенаправлення". Відповіді з цими кодами можуть мати або не мати тіла, за винятком `304`, "Not Modified" (не змінено), яка не повинна мати тіла.
|
||||
* **`400 - 499`** "Помилка клієнта". Це другий тип, який Ви, ймовірно, будете використовувати найчастіше.
|
||||
* Приклад `404`, "Not Found" (не знайдено).
|
||||
* Для загальних помилок клієнта можна використовувати `400`.
|
||||
* `500 - 599` "Помилки сервера". Ви майже ніколи не використовуєте їх напряму. Якщо в коді Вашого застосунку або на сервері щось пішло не так, автоматично буде повернено один із цих кодів статусу.
|
||||
|
||||
/// tip | Порада
|
||||
|
||||
Щоб дізнатися більше про кожен код статусу і призначення кожного з них, перегляньте документацію <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" class="external-link" target="_blank"><abbr title="Mozilla Developer Network">MDN</abbr> про HTTP коди статусу</a>.
|
||||
|
||||
///
|
||||
|
||||
## Легкий спосіб запам'ятати назви
|
||||
|
||||
Розглянемо ще раз попередній приклад:
|
||||
|
||||
{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
|
||||
|
||||
`201` - це код статусу для "Created" (створено).
|
||||
|
||||
Але Вам не потрібно запам'ятовувати, що означає кожен із цих кодів.
|
||||
|
||||
Ви можете використовувати зручні змінні з `fastapi.status`
|
||||
|
||||
{* ../../docs_src/response_status_code/tutorial002.py hl[1,6] *}
|
||||
|
||||
Ці змінні просто для зручності. Вони містять ті ж самі числа, але Ви можете скористатися автозаповненням в редакторі:
|
||||
|
||||
<img src="/img/tutorial/response-status-code/image02.png">
|
||||
|
||||
/// note | Технічні деталі
|
||||
|
||||
Ви також можете використати `from starlette import status`.
|
||||
|
||||
**FastAPI** надає ті ж самі змінні `starlette.status` як `fastapi.status`, просто для зручності розробника. Однак вони походять безпосередньо зі Starlette.
|
||||
|
||||
///
|
||||
|
||||
## Зміна значення за замовчуванням
|
||||
|
||||
Далі, у Посібнику для досвідчених користувачів{.internal-link target=_blank}, Ви дізнаєтесь, як повернути інший код статусу, ніж той, який Ви оголосили тут.
|
||||
|
|
@ -1,12 +1,62 @@
|
|||
# 手动运行服务器 - Uvicorn
|
||||
# 手动运行服务器
|
||||
|
||||
在远程服务器计算机上运行 **FastAPI** 应用程序所需的主要东西是 ASGI 服务器程序,例如 **Uvicorn**。
|
||||
## 使用 `fastapi run` 命令
|
||||
|
||||
有 3 个主要可选方案:
|
||||
简而言之,使用 `fastapi run` 来运行您的 FastAPI 应用程序:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ <font color="#4E9A06">fastapi</font> run <u style="text-decoration-style:solid">main.py</u>
|
||||
|
||||
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting production server 🚀
|
||||
|
||||
Searching for package file structure from directories
|
||||
with <font color="#3465A4">__init__.py</font> files
|
||||
Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> module </font></span> 🐍 main.py
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> code </font></span> Importing the FastAPI app object from the module with
|
||||
the following code:
|
||||
|
||||
<u style="text-decoration-style:solid">from </u><u style="text-decoration-style:solid"><b>main</b></u><u style="text-decoration-style:solid"> import </u><u style="text-decoration-style:solid"><b>app</b></u>
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> app </font></span> Using import string: <font color="#3465A4">main:app</font>
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Server started at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font>
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Documentation at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000/docs</u></font>
|
||||
|
||||
Logs:
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>2306215</b></font><b>]</b>
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup.
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete.
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Uvicorn running on <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font> <b>(</b>Press CTRL+C
|
||||
to quit<b>)</b>
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
这在大多数情况下都能正常运行。😎
|
||||
|
||||
例如,您可以使用该命令在容器、服务器等环境中启动您的 **FastAPI** 应用。
|
||||
|
||||
## ASGI 服务器
|
||||
|
||||
让我们深入了解一些细节。
|
||||
|
||||
FastAPI 使用了一种用于构建 Python Web 框架和服务器的标准,称为 <abbr title="Asynchronous Server Gateway Interface,异步服务器网关接口">ASGI</abbr>。FastAPI 本质上是一个 ASGI Web 框架。
|
||||
|
||||
要在远程服务器上运行 **FastAPI** 应用(或任何其他 ASGI 应用),您需要一个 ASGI 服务器程序,例如 **Uvicorn**。它是 `fastapi` 命令默认使用的 ASGI 服务器。
|
||||
|
||||
除此之外,还有其他一些可选的 ASGI 服务器,例如:
|
||||
|
||||
* <a href="https://www.uvicorn.org/" class="external-link" target="_blank">Uvicorn</a>:高性能 ASGI 服务器。
|
||||
* <a href="https://hypercorn.readthedocs.io/" class="external-link" target="_blank">Hypercorn</a>:与 HTTP/2 和 Trio 等兼容的 ASGI 服务器。
|
||||
* <a href="https://github.com/django/daphne" class="external-link" target="_blank">Daphne</a>:为 Django Channels 构建的 ASGI 服务器。
|
||||
* <a href="https://github.com/emmett-framework/granian" class="external-link" target="_blank">Granian</a>:基于 Rust 的 HTTP 服务器,专为 Python 应用设计。
|
||||
* <a href="https://unit.nginx.org/howto/fastapi/" class="external-link" target="_blank">NGINX Unit</a>:NGINX Unit 是一个轻量级且灵活的 Web 应用运行时环境。
|
||||
|
||||
## 服务器主机和服务器程序
|
||||
|
||||
|
|
@ -21,11 +71,13 @@
|
|||
|
||||
## 安装服务器程序
|
||||
|
||||
您可以使用以下命令安装 ASGI 兼容服务器:
|
||||
当您安装 FastAPI 时,它自带一个生产环境服务器——Uvicorn,并且您可以使用 `fastapi run` 命令来启动它。
|
||||
|
||||
//// tab | Uvicorn
|
||||
不过,您也可以手动安装 ASGI 服务器。
|
||||
|
||||
* <a href="https://www.uvicorn.org/" class="external-link" target="_blank">Uvicorn</a>,一个快如闪电 ASGI 服务器,基于 uvloop 和 httptools 构建。
|
||||
请确保您创建并激活一个[虚拟环境](../virtual-environments.md){.internal-link target=_blank},然后再安装服务器应用程序。
|
||||
|
||||
例如,要安装 Uvicorn,可以运行以下命令:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
|
|
@ -37,39 +89,21 @@ $ pip install "uvicorn[standard]"
|
|||
|
||||
</div>
|
||||
|
||||
类似的流程也适用于任何其他 ASGI 服务器程序。
|
||||
|
||||
/// tip
|
||||
|
||||
通过添加`standard`,Uvicorn 将安装并使用一些推荐的额外依赖项。
|
||||
通过添加 `standard` 选项,Uvicorn 将安装并使用一些推荐的额外依赖项。
|
||||
|
||||
其中包括`uvloop`,它是`asyncio`的高性能替代品,它提供了巨大的并发性能提升。
|
||||
其中包括 `uvloop`,这是 `asyncio` 的高性能替代方案,能够显著提升并发性能。
|
||||
|
||||
当您使用 `pip install "fastapi[standard]"` 安装 FastAPI 时,实际上也会安装 `uvicorn[standard]`。
|
||||
|
||||
///
|
||||
|
||||
////
|
||||
|
||||
//// tab | Hypercorn
|
||||
|
||||
* <a href="https://github.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>,一个也与 HTTP/2 兼容的 ASGI 服务器。
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install hypercorn
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
...或任何其他 ASGI 服务器。
|
||||
|
||||
////
|
||||
|
||||
## 运行服务器程序
|
||||
|
||||
您可以按照之前教程中的相同方式运行应用程序,但不使用`--reload`选项,例如:
|
||||
|
||||
//// tab | Uvicorn
|
||||
如果您手动安装了 ASGI 服务器,通常需要以特定格式传递一个导入字符串,以便服务器能够正确导入您的 FastAPI 应用:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
|
|
@ -81,79 +115,43 @@ $ uvicorn main:app --host 0.0.0.0 --port 80
|
|||
|
||||
</div>
|
||||
|
||||
////
|
||||
/// note
|
||||
|
||||
//// tab | Hypercorn
|
||||
命令 `uvicorn main:app` 的含义如下:
|
||||
|
||||
<div class="termy">
|
||||
* `main`:指的是 `main.py` 文件(即 Python “模块”)。
|
||||
* `app`:指的是 `main.py` 文件中通过 `app = FastAPI()` 创建的对象。
|
||||
|
||||
```console
|
||||
$ hypercorn main:app --bind 0.0.0.0:80
|
||||
它等价于以下导入语句:
|
||||
|
||||
Running on 0.0.0.0:8080 over http (CTRL + C to quit)
|
||||
```Python
|
||||
from main import app
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
/// warning
|
||||
|
||||
如果您正在使用`--reload`选项,请记住删除它。
|
||||
|
||||
`--reload` 选项消耗更多资源,并且更不稳定。
|
||||
|
||||
它在**开发**期间有很大帮助,但您**不应该**在**生产环境**中使用它。
|
||||
|
||||
///
|
||||
|
||||
## Hypercorn with Trio
|
||||
每种 ASGI 服务器程序通常都会有类似的命令,您可以在它们的官方文档中找到更多信息。
|
||||
|
||||
Starlette 和 **FastAPI** 基于 <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a>, 所以它们才能同时与 Python 的标准库 <a href="https://docs.python.org/3/library/asyncio-task.html" class="external-link" target="_blank">asyncio</a> 和<a href="https://trio.readthedocs.io/en/stable/" class="external-link" target="_blank">Trio</a> 兼容。
|
||||
/// warning
|
||||
|
||||
尽管如此,Uvicorn 目前仅与 asyncio 兼容,并且通常使用 <a href="https://github.com/MagicStack/uvloop" class="external-link" target="_blank">`uvloop`</a >, 它是`asyncio`的高性能替代品。
|
||||
Uvicorn 和其他服务器支持 `--reload` 选项,该选项在开发过程中非常有用。
|
||||
|
||||
但如果你想直接使用**Trio**,那么你可以使用**Hypercorn**,因为它支持它。 ✨
|
||||
但 `--reload` 选项会消耗更多资源,且相对不稳定。
|
||||
|
||||
### 安装具有 Trio 的 Hypercorn
|
||||
它对于**开发阶段**非常有帮助,但在**生产环境**中**不应该**使用。
|
||||
|
||||
首先,您需要安装具有 Trio 支持的 Hypercorn:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "hypercorn[trio]"
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### Run with Trio
|
||||
|
||||
然后你可以传递值`trio`给命令行选项`--worker-class`:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ hypercorn main:app --worker-class trio
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
这将通过您的应用程序启动 Hypercorn,并使用 Trio 作为后端。
|
||||
|
||||
现在您可以在应用程序内部使用 Trio。 或者更好的是,您可以使用 AnyIO,使您的代码与 Trio 和 asyncio 兼容。 🎉
|
||||
///
|
||||
|
||||
## 部署概念
|
||||
|
||||
这些示例运行服务器程序(例如 Uvicorn),启动**单个进程**,在所有 IP(`0.0.0.0`)上监听预定义端口(例如`80`)。
|
||||
这些示例运行服务器程序(例如 Uvicorn),启动**单个进程**,在所有 IP(`0.0.0.0`)上监听预定义端口(例如`80`)。
|
||||
|
||||
这是基本思路。 但您可能需要处理一些其他事情,例如:
|
||||
|
||||
* 安全性 - HTTPS
|
||||
* 启动时运行
|
||||
* 重新启动
|
||||
* Replication(运行的进程数)
|
||||
* 复制(运行的进程数)
|
||||
* 内存
|
||||
* 开始前的步骤
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Server Workers - Gunicorn with Uvicorn
|
||||
# 服务器工作进程(Workers) - 使用 Uvicorn 的多工作进程模式
|
||||
|
||||
让我们回顾一下之前的部署概念:
|
||||
|
||||
|
|
@ -9,125 +9,79 @@
|
|||
* 内存
|
||||
* 启动前的先前步骤
|
||||
|
||||
到目前为止,通过文档中的所有教程,您可能已经在**单个进程**上运行了像 Uvicorn 这样的**服务器程序**。
|
||||
到目前为止,在文档中的所有教程中,您可能一直是在运行一个**服务器程序**,例如使用 `fastapi` 命令来启动 Uvicorn,而它默认运行的是**单进程模式**。
|
||||
|
||||
部署应用程序时,您可能希望进行一些**进程复制**,以利用**多核**并能够处理更多请求。
|
||||
部署应用程序时,您可能希望进行一些**进程复制**,以利用**多核** CPU 并能够处理更多请求。
|
||||
|
||||
正如您在上一章有关[部署概念](concepts.md){.internal-link target=_blank}中看到的,您可以使用多种策略。
|
||||
|
||||
在这里我将向您展示如何将 <a href="https://gunicorn.org/" class="external-link" target="_blank">**Gunicorn**</a> 与 **Uvicorn worker 进程** 一起使用。
|
||||
在本章节中,我将向您展示如何使用 `fastapi` 命令或直接使用 `uvicorn` 命令以**多工作进程模式**运行 **Uvicorn**。
|
||||
|
||||
/// info
|
||||
|
||||
如果您正在使用容器,例如 Docker 或 Kubernetes,我将在下一章中告诉您更多相关信息:[容器中的 FastAPI - Docker](docker.md){.internal-link target=_blank}。
|
||||
|
||||
特别是,当在 **Kubernetes** 上运行时,您可能**不想**使用 Gunicorn,而是运行 **每个容器一个 Uvicorn 进程**,但我将在本章后面告诉您这一点。
|
||||
比较特别的是,在 **Kubernetes** 环境中运行时,您通常**不需要**使用多个工作进程,而是**每个容器运行一个 Uvicorn 进程**。不过,我会在本章节的后续部分详细介绍这一点。
|
||||
|
||||
///
|
||||
|
||||
## Gunicorn with Uvicorn Workers
|
||||
## 多个工作进程
|
||||
|
||||
**Gunicorn**主要是一个使用**WSGI标准**的应用服务器。 这意味着 Gunicorn 可以为 Flask 和 Django 等应用程序提供服务。 Gunicorn 本身与 **FastAPI** 不兼容,因为 FastAPI 使用最新的 **<a href="https://asgi.readthedocs.io/en/latest/" class="external-link" target=" _blank">ASGI 标准</a>**。
|
||||
您可以使用 `--workers` 命令行选项来启动多个工作进程:
|
||||
|
||||
但 Gunicorn 支持充当 **进程管理器** 并允许用户告诉它要使用哪个特定的 **worker类**。 然后 Gunicorn 将使用该类启动一个或多个 **worker进程**。
|
||||
//// tab | `fastapi`
|
||||
|
||||
**Uvicorn** 有一个 Gunicorn 兼容的worker类。
|
||||
|
||||
使用这种组合,Gunicorn 将充当 **进程管理器**,监听 **端口** 和 **IP**。 它会将通信**传输**到运行**Uvicorn类**的worker进程。
|
||||
|
||||
然后与Gunicorn兼容的**Uvicorn worker**类将负责将Gunicorn发送的数据转换为ASGI标准以供FastAPI使用。
|
||||
|
||||
## 安装 Gunicorn 和 Uvicorn
|
||||
如果您使用 `fastapi` 命令:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "uvicorn[standard]" gunicorn
|
||||
$ <font color="#4E9A06">fastapi</font> run --workers 4 <u style="text-decoration-style:solid">main.py</u>
|
||||
|
||||
---> 100%
|
||||
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting production server 🚀
|
||||
|
||||
Searching for package file structure from directories with
|
||||
<font color="#3465A4">__init__.py</font> files
|
||||
Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> module </font></span> 🐍 main.py
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> code </font></span> Importing the FastAPI app object from the module with the
|
||||
following code:
|
||||
|
||||
<u style="text-decoration-style:solid">from </u><u style="text-decoration-style:solid"><b>main</b></u><u style="text-decoration-style:solid"> import </u><u style="text-decoration-style:solid"><b>app</b></u>
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> app </font></span> Using import string: <font color="#3465A4">main:app</font>
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Server started at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font>
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Documentation at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000/docs</u></font>
|
||||
|
||||
Logs:
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Uvicorn running on <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font> <b>(</b>Press CTRL+C to
|
||||
quit<b>)</b>
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started parent process <b>[</b><font color="#34E2E2"><b>27365</b></font><b>]</b>
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>27368</b></font><b>]</b>
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>27369</b></font><b>]</b>
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>27370</b></font><b>]</b>
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>27367</b></font><b>]</b>
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup.
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup.
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup.
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup.
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete.
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete.
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete.
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete.
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
这将安装带有`standard`扩展包(以获得高性能)的 Uvicorn 和 Gunicorn。
|
||||
////
|
||||
|
||||
## Run Gunicorn with Uvicorn Workers
|
||||
//// tab | `uvicorn`
|
||||
|
||||
接下来你可以通过以下命令运行Gunicorn:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ gunicorn main:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:80
|
||||
|
||||
[19499] [INFO] Starting gunicorn 20.1.0
|
||||
[19499] [INFO] Listening at: http://0.0.0.0:80 (19499)
|
||||
[19499] [INFO] Using worker: uvicorn.workers.UvicornWorker
|
||||
[19511] [INFO] Booting worker with pid: 19511
|
||||
[19513] [INFO] Booting worker with pid: 19513
|
||||
[19514] [INFO] Booting worker with pid: 19514
|
||||
[19515] [INFO] Booting worker with pid: 19515
|
||||
[19511] [INFO] Started server process [19511]
|
||||
[19511] [INFO] Waiting for application startup.
|
||||
[19511] [INFO] Application startup complete.
|
||||
[19513] [INFO] Started server process [19513]
|
||||
[19513] [INFO] Waiting for application startup.
|
||||
[19513] [INFO] Application startup complete.
|
||||
[19514] [INFO] Started server process [19514]
|
||||
[19514] [INFO] Waiting for application startup.
|
||||
[19514] [INFO] Application startup complete.
|
||||
[19515] [INFO] Started server process [19515]
|
||||
[19515] [INFO] Waiting for application startup.
|
||||
[19515] [INFO] Application startup complete.
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
让我们看看每个选项的含义:
|
||||
|
||||
* `main:app`:这与 Uvicorn 使用的语法相同,`main` 表示名为"`main`"的 Python 模块,因此是文件 `main.py`。 `app` 是 **FastAPI** 应用程序的变量名称。
|
||||
* 你可以想象 `main:app` 相当于一个 Python `import` 语句,例如:
|
||||
|
||||
```Python
|
||||
from main import app
|
||||
```
|
||||
|
||||
* 因此,`main:app` 中的冒号相当于 `from main import app` 中的 Python `import` 部分。
|
||||
|
||||
* `--workers`:要使用的worker进程数量,每个进程将运行一个 Uvicorn worker进程,在本例中为 4 个worker进程。
|
||||
|
||||
* `--worker-class`:在worker进程中使用的与 Gunicorn 兼容的工作类。
|
||||
* 这里我们传递了 Gunicorn 可以导入和使用的类:
|
||||
|
||||
```Python
|
||||
import uvicorn.workers.UvicornWorker
|
||||
```
|
||||
|
||||
* `--bind`:这告诉 Gunicorn 要监听的 IP 和端口,使用冒号 (`:`) 分隔 IP 和端口。
|
||||
* 如果您直接运行 Uvicorn,则可以使用`--host 0.0.0.0`和`--port 80`,而不是`--bind 0.0.0.0:80`(Gunicorn 选项)。
|
||||
|
||||
|
||||
在输出中,您可以看到它显示了每个进程的 **PID**(进程 ID)(它只是一个数字)。
|
||||
|
||||
你可以看到:
|
||||
|
||||
* Gunicorn **进程管理器** 以 PID `19499` 开头(在您的情况下,它将是一个不同的数字)。
|
||||
* 然后它开始`Listening at: http://0.0.0.0:80`。
|
||||
* 然后它检测到它必须使用 `uvicorn.workers.UvicornWorker` 处的worker类。
|
||||
* 然后它启动**4个worker**,每个都有自己的PID:`19511`、`19513`、`19514`和`19515`。
|
||||
|
||||
Gunicorn 还将负责管理**死进程**和**重新启动**新进程(如果需要保持worker数量)。 因此,这在一定程度上有助于上面列表中**重启**的概念。
|
||||
|
||||
尽管如此,您可能还希望有一些外部的东西,以确保在必要时**重新启动 Gunicorn**,并且**在启动时运行它**等。
|
||||
|
||||
## Uvicorn with Workers
|
||||
|
||||
Uvicorn 也有一个选项可以启动和运行多个 **worker进程**。
|
||||
|
||||
然而,到目前为止,Uvicorn 处理worker进程的能力比 Gunicorn 更有限。 因此,如果您想拥有这个级别(Python 级别)的进程管理器,那么最好尝试使用 Gunicorn 作为进程管理器。
|
||||
|
||||
无论如何,您都可以像这样运行它:
|
||||
如果您更想要直接使用 `uvicorn` 命令:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
|
|
@ -151,13 +105,15 @@ $ uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
|
|||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
这里唯一的新选项是 `--workers` 告诉 Uvicorn 启动 4 个工作进程。
|
||||
|
||||
您还可以看到它显示了每个进程的 **PID**,父进程(这是 **进程管理器**)的 PID 为`27365`,每个工作进程的 PID 为:`27368`、`27369`, `27370`和`27367`。
|
||||
您还可以看到它显示了每个进程的 **PID**,父进程(这是**进程管理器**)的 PID 为`27365`,每个工作进程的 PID 为:`27368`、`27369`, `27370`和`27367`。
|
||||
|
||||
## 部署概念
|
||||
|
||||
在这里,您了解了如何使用 **Gunicorn**(或 Uvicorn)管理 **Uvicorn 工作进程**来**并行**应用程序的执行,利用 CPU 中的 **多核**,并 能够满足**更多请求**。
|
||||
在这里,您学习了如何使用多个**工作进程(workers)**来让应用程序的执行**并行化**,充分利用 CPU 的**多核性能**,并能够处理**更多的请求**。
|
||||
|
||||
从上面的部署概念列表来看,使用worker主要有助于**复制**部分,并对**重新启动**有一点帮助,但您仍然需要照顾其他部分:
|
||||
|
||||
|
|
@ -170,15 +126,13 @@ $ uvicorn main:app --host 0.0.0.0 --port 8080 --workers 4
|
|||
|
||||
## 容器和 Docker
|
||||
|
||||
在关于 [容器中的 FastAPI - Docker](docker.md){.internal-link target=_blank} 的下一章中,我将介绍一些可用于处理其他 **部署概念** 的策略。
|
||||
在关于 [容器中的 FastAPI - Docker](docker.md){.internal-link target=_blank} 的下一章中,我将介绍一些可用于处理其他**部署概念**的策略。
|
||||
|
||||
我还将向您展示 **官方 Docker 镜像**,其中包括 **Gunicorn 和 Uvicorn worker** 以及一些对简单情况有用的默认配置。
|
||||
|
||||
在那里,我还将向您展示如何 **从头开始构建自己的镜像** 以运行单个 Uvicorn 进程(没有 Gunicorn)。 这是一个简单的过程,并且可能是您在使用像 **Kubernetes** 这样的分布式容器管理系统时想要做的事情。
|
||||
我将向您展示如何**从零开始构建自己的镜像**,以运行一个单独的 Uvicorn 进程。这个过程相对简单,并且在使用 **Kubernetes** 等分布式容器管理系统时,这通常是您需要采取的方法。
|
||||
|
||||
## 回顾
|
||||
|
||||
您可以使用**Gunicorn**(或Uvicorn)作为Uvicorn工作进程的进程管理器,以利用**多核CPU**,**并行运行多个进程**。
|
||||
您可以在使用 `fastapi` 或 `uvicorn` 命令时,通过 `--workers` CLI 选项启用多个工作进程(workers),以充分利用**多核 CPU**,以**并行运行多个进程**。
|
||||
|
||||
如果您要设置**自己的部署系统**,同时自己处理其他部署概念,则可以使用这些工具和想法。
|
||||
|
||||
|
|
|
|||
|
|
@ -11,34 +11,49 @@
|
|||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --reload
|
||||
$ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid">main.py</u>
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
<span style="color: green;">INFO</span>: Started reloader process [28720]
|
||||
<span style="color: green;">INFO</span>: Started server process [28722]
|
||||
<span style="color: green;">INFO</span>: Waiting for application startup.
|
||||
<span style="color: green;">INFO</span>: Application startup complete.
|
||||
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting development server 🚀
|
||||
|
||||
Searching for package file structure from directories
|
||||
with <font color="#3465A4">__init__.py</font> files
|
||||
Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> module </font></span> 🐍 main.py
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> code </font></span> Importing the FastAPI app object from the module with
|
||||
the following code:
|
||||
|
||||
<u style="text-decoration-style:solid">from </u><u style="text-decoration-style:solid"><b>main</b></u><u style="text-decoration-style:solid"> import </u><u style="text-decoration-style:solid"><b>app</b></u>
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> app </font></span> Using import string: <font color="#3465A4">main:app</font>
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Server started at <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000</u></font>
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Documentation at <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000/docs</u></font>
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> tip </font></span> Running in development mode, for production use:
|
||||
<b>fastapi run</b>
|
||||
|
||||
Logs:
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Will watch for changes in these directories:
|
||||
<b>[</b><font color="#4E9A06">'/home/user/code/awesomeapp'</font><b>]</b>
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Uvicorn running on <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000</u></font> <b>(</b>Press CTRL+C
|
||||
to quit<b>)</b>
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started reloader process <b>[</b><font color="#34E2E2"><b>383138</b></font><b>]</b> using WatchFiles
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>383153</b></font><b>]</b>
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup.
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete.
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
/// note
|
||||
|
||||
`uvicorn main:app` 命令含义如下:
|
||||
|
||||
* `main`:`main.py` 文件(一个 Python「模块」)。
|
||||
* `app`:在 `main.py` 文件中通过 `app = FastAPI()` 创建的对象。
|
||||
* `--reload`:让服务器在更新代码后重新启动。仅在开发时使用该选项。
|
||||
|
||||
///
|
||||
|
||||
在输出中,会有一行信息像下面这样:
|
||||
|
||||
```hl_lines="4"
|
||||
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
|
||||
该行显示了你的应用在本机所提供服务的 URL 地址。
|
||||
|
||||
### 查看
|
||||
|
|
@ -63,7 +78,7 @@ INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
|||
|
||||
前往 <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>。
|
||||
|
||||
你将会看到可选的自动生成文档 (由 <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a> 提供):
|
||||
你将会看到可选的自动生成文档 (由 <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a> 提供):
|
||||
|
||||

|
||||
|
||||
|
|
@ -77,9 +92,9 @@ INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
|||
|
||||
#### API「模式」
|
||||
|
||||
在这种场景下,OpenAPI 是一种规定如何定义 API 模式的规范。
|
||||
在这种场景下,<a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> 是一种规定如何定义 API 模式的规范。
|
||||
|
||||
定义的 OpenAPI 模式将包括你的 API 路径,以及它们可能使用的参数等等。
|
||||
「模式」的定义包括你的 API 路径,以及它们可能使用的参数等等。
|
||||
|
||||
#### 数据「模式」
|
||||
|
||||
|
|
@ -93,7 +108,7 @@ OpenAPI 为你的 API 定义 API 模式。该模式中包含了你的 API 发送
|
|||
|
||||
#### 查看 `openapi.json`
|
||||
|
||||
如果你对原始的 OpenAPI 模式长什么样子感到好奇,其实它只是一个自动生成的包含了所有 API 描述的 JSON。
|
||||
如果你对原始的 OpenAPI 模式长什么样子感到好奇,FastAPI 自动生成了包含所有 API 描述的 JSON(模式)。
|
||||
|
||||
你可以直接在:<a href="http://127.0.0.1:8000/openapi.json" class="external-link" target="_blank">http://127.0.0.1:8000/openapi.json</a> 看到它。
|
||||
|
||||
|
|
@ -101,7 +116,7 @@ OpenAPI 为你的 API 定义 API 模式。该模式中包含了你的 API 发送
|
|||
|
||||
```JSON
|
||||
{
|
||||
"openapi": "3.0.2",
|
||||
"openapi": "3.1.0",
|
||||
"info": {
|
||||
"title": "FastAPI",
|
||||
"version": "0.1.0"
|
||||
|
|
@ -140,7 +155,7 @@ OpenAPI 为你的 API 定义 API 模式。该模式中包含了你的 API 发送
|
|||
|
||||
`FastAPI` 是直接从 `Starlette` 继承的类。
|
||||
|
||||
你可以通过 `FastAPI` 使用所有的 Starlette 的功能。
|
||||
你可以通过 `FastAPI` 使用所有的 <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> 的功能。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -152,34 +167,6 @@ OpenAPI 为你的 API 定义 API 模式。该模式中包含了你的 API 发送
|
|||
|
||||
这个实例将是创建你所有 API 的主要交互对象。
|
||||
|
||||
这个 `app` 同样在如下命令中被 `uvicorn` 所引用:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --reload
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
如果你像下面这样创建应用:
|
||||
|
||||
{* ../../docs_src/first_steps/tutorial002.py hl[3] *}
|
||||
|
||||
将代码放入 `main.py` 文件中,然后你可以像下面这样运行 `uvicorn`:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:my_awesome_api --reload
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### 步骤 3:创建一个*路径操作*
|
||||
|
||||
#### 路径
|
||||
|
|
@ -279,13 +266,13 @@ https://example.com/items/foo
|
|||
|
||||
/// tip
|
||||
|
||||
您可以随意使用任何一个操作(HTTP方法)。
|
||||
你可以随意使用任何一个操作(HTTP方法)。
|
||||
|
||||
**FastAPI** 没有强制要求操作有任何特定的含义。
|
||||
|
||||
此处提供的信息仅作为指导,而不是要求。
|
||||
|
||||
比如,当使用 GraphQL 时通常你所有的动作都通过 `post` 一种方法执行。
|
||||
比如,当使用 GraphQL 时通常你所有的动作都通过 `POST` 一种方法执行。
|
||||
|
||||
///
|
||||
|
||||
|
|
@ -331,6 +318,6 @@ https://example.com/items/foo
|
|||
|
||||
* 导入 `FastAPI`。
|
||||
* 创建一个 `app` 实例。
|
||||
* 编写一个**路径操作装饰器**(如 `@app.get("/")`)。
|
||||
* 编写一个**路径操作函数**(如上面的 `def root(): ...`)。
|
||||
* 运行开发服务器(如 `uvicorn main:app --reload`)。
|
||||
* 编写一个**路径操作装饰器**,如 `@app.get("/")`。
|
||||
* 定义一个**路径操作函数**,如 `def root(): ...`。
|
||||
* 使用命令 `fastapi dev` 运行开发服务器。
|
||||
|
|
|
|||
|
|
@ -1,34 +1,58 @@
|
|||
# 教程 - 用户指南
|
||||
|
||||
本教程将一步步向你展示如何使用 **FastAPI** 的绝大部分特性。
|
||||
本教程将一步步向您展示如何使用 **FastAPI** 的绝大部分特性。
|
||||
|
||||
各个章节的内容循序渐进,但是又围绕着单独的主题,所以你可以直接跳转到某个章节以解决你的特定需求。
|
||||
各个章节的内容循序渐进,但是又围绕着单独的主题,所以您可以直接跳转到某个章节以解决您的特定需求。
|
||||
|
||||
本教程同样可以作为将来的参考手册。
|
||||
|
||||
你可以随时回到本教程并查阅你需要的内容。
|
||||
本教程同样可以作为将来的参考手册,所以您可以随时回到本教程并查阅您需要的内容。
|
||||
|
||||
## 运行代码
|
||||
|
||||
所有代码片段都可以复制后直接使用(它们实际上是经过测试的 Python 文件)。
|
||||
|
||||
要运行任何示例,请将代码复制到 `main.py` 文件中,然后使用以下命令启动 `uvicorn`:
|
||||
要运行任何示例,请将代码复制到 `main.py` 文件中,然后使用以下命令启动 `fastapi dev`:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --reload
|
||||
$ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid">main.py</u>
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
<span style="color: green;">INFO</span>: Started reloader process [28720]
|
||||
<span style="color: green;">INFO</span>: Started server process [28722]
|
||||
<span style="color: green;">INFO</span>: Waiting for application startup.
|
||||
<span style="color: green;">INFO</span>: Application startup complete.
|
||||
<span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span> Starting development server 🚀
|
||||
|
||||
Searching for package file structure from directories
|
||||
with <font color="#3465A4">__init__.py</font> files
|
||||
Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> module </font></span> 🐍 main.py
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> code </font></span> Importing the FastAPI app object from the module with
|
||||
the following code:
|
||||
|
||||
<u style="text-decoration-style:solid">from </u><u style="text-decoration-style:solid"><b>main</b></u><u style="text-decoration-style:solid"> import </u><u style="text-decoration-style:solid"><b>app</b></u>
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> app </font></span> Using import string: <font color="#3465A4">main:app</font>
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Server started at <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000</u></font>
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> server </font></span> Documentation at <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000/docs</u></font>
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> tip </font></span> Running in development mode, for production use:
|
||||
<b>fastapi run</b>
|
||||
|
||||
Logs:
|
||||
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Will watch for changes in these directories:
|
||||
<b>[</b><font color="#4E9A06">'/home/user/code/awesomeapp'</font><b>]</b>
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Uvicorn running on <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000</u></font> <b>(</b>Press CTRL+C
|
||||
to quit<b>)</b>
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started reloader process <b>[</b><font color="#34E2E2"><b>383138</b></font><b>]</b> using WatchFiles
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Started server process <b>[</b><font color="#34E2E2"><b>383153</b></font><b>]</b>
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Waiting for application startup.
|
||||
<span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span> Application startup complete.
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
强烈建议你在本地编写或复制代码,对其进行编辑并运行。
|
||||
**强烈建议**您在本地编写或复制代码,对其进行编辑并运行。
|
||||
|
||||
在编辑器中使用 FastAPI 会真正地展现出它的优势:只需要编写很少的代码,所有的类型检查,代码补全等等。
|
||||
|
||||
|
|
@ -36,48 +60,34 @@ $ uvicorn main:app --reload
|
|||
|
||||
## 安装 FastAPI
|
||||
|
||||
第一个步骤是安装 FastAPI。
|
||||
第一个步骤是安装 FastAPI.
|
||||
|
||||
为了使用本教程,你可能需要安装所有的可选依赖及对应功能:
|
||||
请确保您创建并激活一个[虚拟环境](../virtual-environments.md){.internal-link target=_blank},然后**安装 FastAPI**:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "fastapi[all]"
|
||||
$ pip install "fastapi[standard]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
......以上安装还包括了 `uvicorn`,你可以将其用作运行代码的服务器。
|
||||
|
||||
/// note
|
||||
|
||||
你也可以分开来安装。
|
||||
当您使用 `pip install "fastapi[standard]"` 进行安装时,它会附带一些默认的可选标准依赖项。
|
||||
|
||||
假如你想将应用程序部署到生产环境,你可能要执行以下操作:
|
||||
|
||||
```
|
||||
pip install fastapi
|
||||
```
|
||||
|
||||
并且安装`uvicorn`来作为服务器:
|
||||
|
||||
```
|
||||
pip install "uvicorn[standard]"
|
||||
```
|
||||
|
||||
然后对你想使用的每个可选依赖项也执行相同的操作。
|
||||
如果您不想安装这些可选依赖,可以选择安装 `pip install fastapi`。
|
||||
|
||||
///
|
||||
|
||||
## 进阶用户指南
|
||||
|
||||
在本**教程-用户指南**之后,你可以阅读**进阶用户指南**。
|
||||
在本**教程-用户指南**之后,您可以阅读**进阶用户指南**。
|
||||
|
||||
**进阶用户指南**以本教程为基础,使用相同的概念,并教授一些额外的特性。
|
||||
|
||||
但是你应该先阅读**教程-用户指南**(即你现在正在阅读的内容)。
|
||||
但是您应该先阅读**教程-用户指南**(即您现在正在阅读的内容)。
|
||||
|
||||
教程经过精心设计,使你可以仅通过**教程-用户指南**来开发一个完整的应用程序,然后根据你的需要,使用**进阶用户指南**中的一些其他概念,以不同的方式来扩展它。
|
||||
教程经过精心设计,使您可以仅通过**教程-用户指南**来开发一个完整的应用程序,然后根据您的需要,使用**进阶用户指南**中的一些其他概念,以不同的方式来扩展它。
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
from typing import List, Union
|
||||
|
||||
from fastapi import FastAPI, Header
|
||||
from pydantic import BaseModel
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
class CommonHeaders(BaseModel):
|
||||
host: str
|
||||
save_data: bool
|
||||
if_modified_since: Union[str, None] = None
|
||||
traceparent: Union[str, None] = None
|
||||
x_tag: List[str] = []
|
||||
|
||||
|
||||
@app.get("/items/")
|
||||
async def read_items(headers: CommonHeaders = Header(convert_underscores=False)):
|
||||
return headers
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
from typing import List, Union
|
||||
|
||||
from fastapi import FastAPI, Header
|
||||
from pydantic import BaseModel
|
||||
from typing_extensions import Annotated
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
class CommonHeaders(BaseModel):
|
||||
host: str
|
||||
save_data: bool
|
||||
if_modified_since: Union[str, None] = None
|
||||
traceparent: Union[str, None] = None
|
||||
x_tag: List[str] = []
|
||||
|
||||
|
||||
@app.get("/items/")
|
||||
async def read_items(
|
||||
headers: Annotated[CommonHeaders, Header(convert_underscores=False)],
|
||||
):
|
||||
return headers
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
from typing import Annotated
|
||||
|
||||
from fastapi import FastAPI, Header
|
||||
from pydantic import BaseModel
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
class CommonHeaders(BaseModel):
|
||||
host: str
|
||||
save_data: bool
|
||||
if_modified_since: str | None = None
|
||||
traceparent: str | None = None
|
||||
x_tag: list[str] = []
|
||||
|
||||
|
||||
@app.get("/items/")
|
||||
async def read_items(
|
||||
headers: Annotated[CommonHeaders, Header(convert_underscores=False)],
|
||||
):
|
||||
return headers
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
from typing import Annotated, Union
|
||||
|
||||
from fastapi import FastAPI, Header
|
||||
from pydantic import BaseModel
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
class CommonHeaders(BaseModel):
|
||||
host: str
|
||||
save_data: bool
|
||||
if_modified_since: Union[str, None] = None
|
||||
traceparent: Union[str, None] = None
|
||||
x_tag: list[str] = []
|
||||
|
||||
|
||||
@app.get("/items/")
|
||||
async def read_items(
|
||||
headers: Annotated[CommonHeaders, Header(convert_underscores=False)],
|
||||
):
|
||||
return headers
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
from fastapi import FastAPI, Header
|
||||
from pydantic import BaseModel
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
class CommonHeaders(BaseModel):
|
||||
host: str
|
||||
save_data: bool
|
||||
if_modified_since: str | None = None
|
||||
traceparent: str | None = None
|
||||
x_tag: list[str] = []
|
||||
|
||||
|
||||
@app.get("/items/")
|
||||
async def read_items(headers: CommonHeaders = Header(convert_underscores=False)):
|
||||
return headers
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI, Header
|
||||
from pydantic import BaseModel
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
class CommonHeaders(BaseModel):
|
||||
host: str
|
||||
save_data: bool
|
||||
if_modified_since: Union[str, None] = None
|
||||
traceparent: Union[str, None] = None
|
||||
x_tag: list[str] = []
|
||||
|
||||
|
||||
@app.get("/items/")
|
||||
async def read_items(headers: CommonHeaders = Header(convert_underscores=False)):
|
||||
return headers
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
"""FastAPI framework, high performance, easy to learn, fast to code, ready for production"""
|
||||
|
||||
__version__ = "0.115.11"
|
||||
__version__ = "0.115.12"
|
||||
|
||||
from starlette import status as status
|
||||
|
||||
|
|
|
|||
|
|
@ -750,9 +750,15 @@ def request_params_to_args(
|
|||
first_field = fields[0]
|
||||
fields_to_extract = fields
|
||||
single_not_embedded_field = False
|
||||
default_convert_underscores = True
|
||||
if len(fields) == 1 and lenient_issubclass(first_field.type_, BaseModel):
|
||||
fields_to_extract = get_cached_model_fields(first_field.type_)
|
||||
single_not_embedded_field = True
|
||||
# If headers are in a Pydantic model, the way to disable convert_underscores
|
||||
# would be with Header(convert_underscores=False) at the Pydantic model level
|
||||
default_convert_underscores = getattr(
|
||||
first_field.field_info, "convert_underscores", True
|
||||
)
|
||||
|
||||
params_to_process: Dict[str, Any] = {}
|
||||
|
||||
|
|
@ -763,7 +769,9 @@ def request_params_to_args(
|
|||
if isinstance(received_params, Headers):
|
||||
# Handle fields extracted from a Pydantic Model for a header, each field
|
||||
# doesn't have a FieldInfo of type Header with the default convert_underscores=True
|
||||
convert_underscores = getattr(field.field_info, "convert_underscores", True)
|
||||
convert_underscores = getattr(
|
||||
field.field_info, "convert_underscores", default_convert_underscores
|
||||
)
|
||||
if convert_underscores:
|
||||
alias = (
|
||||
field.alias
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ from fastapi.utils import (
|
|||
generate_operation_id_for_path,
|
||||
is_body_allowed_for_status_code,
|
||||
)
|
||||
from pydantic import BaseModel
|
||||
from starlette.responses import JSONResponse
|
||||
from starlette.routing import BaseRoute
|
||||
from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY
|
||||
|
|
@ -113,6 +114,13 @@ def _get_openapi_operation_parameters(
|
|||
(ParamTypes.header, header_params),
|
||||
(ParamTypes.cookie, cookie_params),
|
||||
]
|
||||
default_convert_underscores = True
|
||||
if len(flat_dependant.header_params) == 1:
|
||||
first_field = flat_dependant.header_params[0]
|
||||
if lenient_issubclass(first_field.type_, BaseModel):
|
||||
default_convert_underscores = getattr(
|
||||
first_field.field_info, "convert_underscores", True
|
||||
)
|
||||
for param_type, param_group in parameter_groups:
|
||||
for param in param_group:
|
||||
field_info = param.field_info
|
||||
|
|
@ -126,8 +134,21 @@ def _get_openapi_operation_parameters(
|
|||
field_mapping=field_mapping,
|
||||
separate_input_output_schemas=separate_input_output_schemas,
|
||||
)
|
||||
name = param.alias
|
||||
convert_underscores = getattr(
|
||||
param.field_info,
|
||||
"convert_underscores",
|
||||
default_convert_underscores,
|
||||
)
|
||||
if (
|
||||
param_type == ParamTypes.header
|
||||
and param.alias == param.name
|
||||
and convert_underscores
|
||||
):
|
||||
name = param.name.replace("_", "-")
|
||||
|
||||
parameter = {
|
||||
"name": param.alias,
|
||||
"name": name,
|
||||
"in": param_type.value,
|
||||
"required": param.required,
|
||||
"schema": param_schema,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# For mkdocstrings and tests
|
||||
httpx >=0.23.0,<0.28.0
|
||||
# For linting and generating docs versions
|
||||
ruff ==0.9.4
|
||||
ruff ==0.11.2
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
pytest >=7.1.3,<9.0.0
|
||||
coverage[toml] >= 6.5.0,< 8.0
|
||||
mypy ==1.8.0
|
||||
dirty-equals ==0.8.0
|
||||
dirty-equals ==0.9.0
|
||||
sqlmodel==0.0.23
|
||||
flask >=1.1.2,<4.0.0
|
||||
anyio[trio] >=3.2.1,<5.0.0
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
pydantic-ai==0.0.15
|
||||
pydantic-ai==0.0.30
|
||||
|
|
|
|||
|
|
@ -129,13 +129,13 @@ def test_openapi_schema(client: TestClient):
|
|||
"schema": {"type": "string", "title": "Host"},
|
||||
},
|
||||
{
|
||||
"name": "save_data",
|
||||
"name": "save-data",
|
||||
"in": "header",
|
||||
"required": True,
|
||||
"schema": {"type": "boolean", "title": "Save Data"},
|
||||
},
|
||||
{
|
||||
"name": "if_modified_since",
|
||||
"name": "if-modified-since",
|
||||
"in": "header",
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
|
|
@ -171,7 +171,7 @@ def test_openapi_schema(client: TestClient):
|
|||
),
|
||||
},
|
||||
{
|
||||
"name": "x_tag",
|
||||
"name": "x-tag",
|
||||
"in": "header",
|
||||
"required": False,
|
||||
"schema": {
|
||||
|
|
|
|||
|
|
@ -140,13 +140,13 @@ def test_openapi_schema(client: TestClient):
|
|||
"schema": {"type": "string", "title": "Host"},
|
||||
},
|
||||
{
|
||||
"name": "save_data",
|
||||
"name": "save-data",
|
||||
"in": "header",
|
||||
"required": True,
|
||||
"schema": {"type": "boolean", "title": "Save Data"},
|
||||
},
|
||||
{
|
||||
"name": "if_modified_since",
|
||||
"name": "if-modified-since",
|
||||
"in": "header",
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
|
|
@ -182,7 +182,7 @@ def test_openapi_schema(client: TestClient):
|
|||
),
|
||||
},
|
||||
{
|
||||
"name": "x_tag",
|
||||
"name": "x-tag",
|
||||
"in": "header",
|
||||
"required": False,
|
||||
"schema": {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,285 @@
|
|||
import importlib
|
||||
|
||||
import pytest
|
||||
from dirty_equals import IsDict
|
||||
from fastapi.testclient import TestClient
|
||||
from inline_snapshot import snapshot
|
||||
|
||||
from tests.utils import needs_py39, needs_py310
|
||||
|
||||
|
||||
@pytest.fixture(
|
||||
name="client",
|
||||
params=[
|
||||
"tutorial003",
|
||||
pytest.param("tutorial003_py39", marks=needs_py39),
|
||||
pytest.param("tutorial003_py310", marks=needs_py310),
|
||||
"tutorial003_an",
|
||||
pytest.param("tutorial003_an_py39", marks=needs_py39),
|
||||
pytest.param("tutorial003_an_py310", marks=needs_py310),
|
||||
],
|
||||
)
|
||||
def get_client(request: pytest.FixtureRequest):
|
||||
mod = importlib.import_module(f"docs_src.header_param_models.{request.param}")
|
||||
|
||||
client = TestClient(mod.app)
|
||||
return client
|
||||
|
||||
|
||||
def test_header_param_model(client: TestClient):
|
||||
response = client.get(
|
||||
"/items/",
|
||||
headers=[
|
||||
("save_data", "true"),
|
||||
("if_modified_since", "yesterday"),
|
||||
("traceparent", "123"),
|
||||
("x_tag", "one"),
|
||||
("x_tag", "two"),
|
||||
],
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {
|
||||
"host": "testserver",
|
||||
"save_data": True,
|
||||
"if_modified_since": "yesterday",
|
||||
"traceparent": "123",
|
||||
"x_tag": ["one", "two"],
|
||||
}
|
||||
|
||||
|
||||
def test_header_param_model_no_underscore(client: TestClient):
|
||||
response = client.get(
|
||||
"/items/",
|
||||
headers=[
|
||||
("save-data", "true"),
|
||||
("if-modified-since", "yesterday"),
|
||||
("traceparent", "123"),
|
||||
("x-tag", "one"),
|
||||
("x-tag", "two"),
|
||||
],
|
||||
)
|
||||
assert response.status_code == 422
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"detail": [
|
||||
IsDict(
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "save_data"],
|
||||
"msg": "Field required",
|
||||
"input": {
|
||||
"host": "testserver",
|
||||
"traceparent": "123",
|
||||
"x_tag": [],
|
||||
"accept": "*/*",
|
||||
"accept-encoding": "gzip, deflate",
|
||||
"connection": "keep-alive",
|
||||
"user-agent": "testclient",
|
||||
"save-data": "true",
|
||||
"if-modified-since": "yesterday",
|
||||
"x-tag": "two",
|
||||
},
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"type": "value_error.missing",
|
||||
"loc": ["header", "save_data"],
|
||||
"msg": "field required",
|
||||
}
|
||||
)
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def test_header_param_model_defaults(client: TestClient):
|
||||
response = client.get("/items/", headers=[("save_data", "true")])
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {
|
||||
"host": "testserver",
|
||||
"save_data": True,
|
||||
"if_modified_since": None,
|
||||
"traceparent": None,
|
||||
"x_tag": [],
|
||||
}
|
||||
|
||||
|
||||
def test_header_param_model_invalid(client: TestClient):
|
||||
response = client.get("/items/")
|
||||
assert response.status_code == 422
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"detail": [
|
||||
IsDict(
|
||||
{
|
||||
"type": "missing",
|
||||
"loc": ["header", "save_data"],
|
||||
"msg": "Field required",
|
||||
"input": {
|
||||
"x_tag": [],
|
||||
"host": "testserver",
|
||||
"accept": "*/*",
|
||||
"accept-encoding": "gzip, deflate",
|
||||
"connection": "keep-alive",
|
||||
"user-agent": "testclient",
|
||||
},
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"type": "value_error.missing",
|
||||
"loc": ["header", "save_data"],
|
||||
"msg": "field required",
|
||||
}
|
||||
)
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def test_header_param_model_extra(client: TestClient):
|
||||
response = client.get(
|
||||
"/items/", headers=[("save_data", "true"), ("tool", "plumbus")]
|
||||
)
|
||||
assert response.status_code == 200, response.text
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"host": "testserver",
|
||||
"save_data": True,
|
||||
"if_modified_since": None,
|
||||
"traceparent": None,
|
||||
"x_tag": [],
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def test_openapi_schema(client: TestClient):
|
||||
response = client.get("/openapi.json")
|
||||
assert response.status_code == 200, response.text
|
||||
assert response.json() == snapshot(
|
||||
{
|
||||
"openapi": "3.1.0",
|
||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||
"paths": {
|
||||
"/items/": {
|
||||
"get": {
|
||||
"summary": "Read Items",
|
||||
"operationId": "read_items_items__get",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "host",
|
||||
"in": "header",
|
||||
"required": True,
|
||||
"schema": {"type": "string", "title": "Host"},
|
||||
},
|
||||
{
|
||||
"name": "save_data",
|
||||
"in": "header",
|
||||
"required": True,
|
||||
"schema": {"type": "boolean", "title": "Save Data"},
|
||||
},
|
||||
{
|
||||
"name": "if_modified_since",
|
||||
"in": "header",
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "If Modified Since",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"type": "string",
|
||||
"title": "If Modified Since",
|
||||
}
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "traceparent",
|
||||
"in": "header",
|
||||
"required": False,
|
||||
"schema": IsDict(
|
||||
{
|
||||
"anyOf": [{"type": "string"}, {"type": "null"}],
|
||||
"title": "Traceparent",
|
||||
}
|
||||
)
|
||||
| IsDict(
|
||||
# TODO: remove when deprecating Pydantic v1
|
||||
{
|
||||
"type": "string",
|
||||
"title": "Traceparent",
|
||||
}
|
||||
),
|
||||
},
|
||||
{
|
||||
"name": "x_tag",
|
||||
"in": "header",
|
||||
"required": False,
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
"default": [],
|
||||
"title": "X Tag",
|
||||
},
|
||||
},
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {"application/json": {"schema": {}}},
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"HTTPValidationError": {
|
||||
"properties": {
|
||||
"detail": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ValidationError"
|
||||
},
|
||||
"type": "array",
|
||||
"title": "Detail",
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"title": "HTTPValidationError",
|
||||
},
|
||||
"ValidationError": {
|
||||
"properties": {
|
||||
"loc": {
|
||||
"items": {
|
||||
"anyOf": [{"type": "string"}, {"type": "integer"}]
|
||||
},
|
||||
"type": "array",
|
||||
"title": "Location",
|
||||
},
|
||||
"msg": {"type": "string", "title": "Message"},
|
||||
"type": {"type": "string", "title": "Error Type"},
|
||||
},
|
||||
"type": "object",
|
||||
"required": ["loc", "msg", "type"],
|
||||
"title": "ValidationError",
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
Loading…
Reference in New Issue