Browse Source

Merge branch 'master' into fix/issue-142-apikey-docs

pull/13434/head
Dale 2 weeks ago
committed by GitHub
parent
commit
5d676bc80c
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      .pre-commit-config.yaml
  2. 38
      docs/en/data/contributors.yml
  3. 177
      docs/en/data/github_sponsors.yml
  4. 6
      docs/en/data/sponsors.yml
  5. 336
      docs/en/data/topic_repos.yml
  6. 199
      docs/en/data/translation_reviewers.yml
  7. 56
      docs/en/data/translators.yml
  8. 15
      docs/en/docs/advanced/index.md
  9. 25
      docs/en/docs/release-notes.md
  10. 64
      docs/en/docs/tutorial/query-params-str-validations.md
  11. 273
      docs/ko/docs/tutorial/security/oauth2-jwt.md
  12. 17
      docs/vi/docs/deployment/cloud.md
  13. 31
      docs_src/query_params_str_validations/tutorial015_an.py
  14. 30
      docs_src/query_params_str_validations/tutorial015_an_py310.py
  15. 30
      docs_src/query_params_str_validations/tutorial015_an_py39.py
  16. 2
      fastapi/__init__.py
  17. 50
      fastapi/dependencies/utils.py
  18. 12
      fastapi/openapi/utils.py
  19. 24
      fastapi/routing.py
  20. 2
      requirements-docs-tests.txt
  21. 2
      requirements-docs.txt
  22. 2
      requirements-tests.txt
  23. 12
      scripts/translate.py
  24. 22
      tests/test_analyze_param.py
  25. 6
      tests/test_enforce_once_required_parameter.py
  26. 4
      tests/test_generic_parameterless_depends.py
  27. 6
      tests/test_repeated_dependency_schema.py
  28. 48
      tests/test_tutorial/test_configure_swagger_ui/test_tutorial001.py
  29. 54
      tests/test_tutorial/test_configure_swagger_ui/test_tutorial002.py
  30. 54
      tests/test_tutorial/test_configure_swagger_ui/test_tutorial003.py
  31. 143
      tests/test_tutorial/test_query_params_str_validations/test_tutorial015.py
  32. 6
      tests/test_tutorial/test_sql_databases/test_tutorial002.py

2
.pre-commit-config.yaml

@ -14,7 +14,7 @@ repos:
- id: end-of-file-fixer - id: end-of-file-fixer
- id: trailing-whitespace - id: trailing-whitespace
- repo: https://github.com/astral-sh/ruff-pre-commit - repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.7.4 rev: v0.9.4
hooks: hooks:
- id: ruff - id: ruff
args: args:

38
docs/en/data/contributors.yml

@ -1,11 +1,11 @@
tiangolo: tiangolo:
login: tiangolo login: tiangolo
count: 713 count: 723
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4 avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
url: https://github.com/tiangolo url: https://github.com/tiangolo
dependabot: dependabot:
login: dependabot login: dependabot
count: 90 count: 94
avatarUrl: https://avatars.githubusercontent.com/in/29110?v=4 avatarUrl: https://avatars.githubusercontent.com/in/29110?v=4
url: https://github.com/apps/dependabot url: https://github.com/apps/dependabot
alejsdev: alejsdev:
@ -68,6 +68,11 @@ vishnuvskvkl:
count: 8 count: 8
avatarUrl: https://avatars.githubusercontent.com/u/84698110?u=8af5de0520dd4fa195f53c2850a26f57c0f6bc64&v=4 avatarUrl: https://avatars.githubusercontent.com/u/84698110?u=8af5de0520dd4fa195f53c2850a26f57c0f6bc64&v=4
url: https://github.com/vishnuvskvkl url: https://github.com/vishnuvskvkl
svlandeg:
login: svlandeg
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4
url: https://github.com/svlandeg
alissadb: alissadb:
login: alissadb login: alissadb
count: 6 count: 6
@ -88,16 +93,16 @@ waynerv:
count: 5 count: 5
avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4 avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
url: https://github.com/waynerv url: https://github.com/waynerv
svlandeg:
login: svlandeg
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4
url: https://github.com/svlandeg
krishnamadhavan: krishnamadhavan:
login: krishnamadhavan login: krishnamadhavan
count: 5 count: 5
avatarUrl: https://avatars.githubusercontent.com/u/31798870?u=950693b28f3ae01105fd545c046e46ca3d31ab06&v=4 avatarUrl: https://avatars.githubusercontent.com/u/31798870?u=950693b28f3ae01105fd545c046e46ca3d31ab06&v=4
url: https://github.com/krishnamadhavan url: https://github.com/krishnamadhavan
alv2017:
login: alv2017
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
url: https://github.com/alv2017
jekirl: jekirl:
login: jekirl login: jekirl
count: 4 count: 4
@ -121,7 +126,7 @@ adriangb:
iudeen: iudeen:
login: iudeen login: iudeen
count: 4 count: 4
avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4 avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=f09cdd745e5bf16138f29b42732dd57c7f02bee1&v=4
url: https://github.com/iudeen url: https://github.com/iudeen
philipokiokio: philipokiokio:
login: philipokiokio login: philipokiokio
@ -211,7 +216,7 @@ TeoZosa:
graingert: graingert:
login: graingert login: graingert
count: 3 count: 3
avatarUrl: https://avatars.githubusercontent.com/u/413772?u=64b77b6aa405c68a9c6bcf45f84257c66eea5f32&v=4 avatarUrl: https://avatars.githubusercontent.com/u/413772?v=4
url: https://github.com/graingert url: https://github.com/graingert
jaystone776: jaystone776:
login: jaystone776 login: jaystone776
@ -233,6 +238,11 @@ papb:
count: 3 count: 3
avatarUrl: https://avatars.githubusercontent.com/u/20914054?u=890511fae7ea90d887e2a65ce44a1775abba38d5&v=4 avatarUrl: https://avatars.githubusercontent.com/u/20914054?u=890511fae7ea90d887e2a65ce44a1775abba38d5&v=4
url: https://github.com/papb url: https://github.com/papb
musicinmybrain:
login: musicinmybrain
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/6898909?u=9010312053e7141383b9bdf538036c7f37fbaba0&v=4
url: https://github.com/musicinmybrain
gitworkflows: gitworkflows:
login: gitworkflows login: gitworkflows
count: 3 count: 3
@ -468,11 +478,6 @@ yezz123:
count: 2 count: 2
avatarUrl: https://avatars.githubusercontent.com/u/52716203?u=d7062cbc6eb7671d5dc9cc0e32a24ae335e0f225&v=4 avatarUrl: https://avatars.githubusercontent.com/u/52716203?u=d7062cbc6eb7671d5dc9cc0e32a24ae335e0f225&v=4
url: https://github.com/yezz123 url: https://github.com/yezz123
musicinmybrain:
login: musicinmybrain
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/6898909?u=9010312053e7141383b9bdf538036c7f37fbaba0&v=4
url: https://github.com/musicinmybrain
softwarebloat: softwarebloat:
login: softwarebloat login: softwarebloat
count: 2 count: 2
@ -518,3 +523,8 @@ DanielKusyDev:
count: 2 count: 2
avatarUrl: https://avatars.githubusercontent.com/u/36250676?u=2ea6114ff751fc48b55f231987a0e2582c6b1bd2&v=4 avatarUrl: https://avatars.githubusercontent.com/u/36250676?u=2ea6114ff751fc48b55f231987a0e2582c6b1bd2&v=4
url: https://github.com/DanielKusyDev url: https://github.com/DanielKusyDev
DanielYang59:
login: DanielYang59
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/80093591?u=63873f701c7c74aac83c906800a1dddc0bc8c92f&v=4
url: https://github.com/DanielYang59

177
docs/en/data/github_sponsors.yml

@ -1,10 +1,10 @@
sponsors: sponsors:
- - login: bump-sh - - login: renderinc
avatarUrl: https://avatars.githubusercontent.com/u/33217836?v=4
url: https://github.com/bump-sh
- login: renderinc
avatarUrl: https://avatars.githubusercontent.com/u/36424661?v=4 avatarUrl: https://avatars.githubusercontent.com/u/36424661?v=4
url: https://github.com/renderinc url: https://github.com/renderinc
- login: bump-sh
avatarUrl: https://avatars.githubusercontent.com/u/33217836?v=4
url: https://github.com/bump-sh
- login: Nixtla - login: Nixtla
avatarUrl: https://avatars.githubusercontent.com/u/79945230?v=4 avatarUrl: https://avatars.githubusercontent.com/u/79945230?v=4
url: https://github.com/Nixtla url: https://github.com/Nixtla
@ -23,6 +23,9 @@ sponsors:
- login: zuplo - login: zuplo
avatarUrl: https://avatars.githubusercontent.com/u/85497839?v=4 avatarUrl: https://avatars.githubusercontent.com/u/85497839?v=4
url: https://github.com/zuplo url: https://github.com/zuplo
- login: coderabbitai
avatarUrl: https://avatars.githubusercontent.com/u/132028505?v=4
url: https://github.com/coderabbitai
- login: porter-dev - login: porter-dev
avatarUrl: https://avatars.githubusercontent.com/u/62078005?v=4 avatarUrl: https://avatars.githubusercontent.com/u/62078005?v=4
url: https://github.com/porter-dev url: https://github.com/porter-dev
@ -59,6 +62,9 @@ sponsors:
- login: Ponte-Energy-Partners - login: Ponte-Energy-Partners
avatarUrl: https://avatars.githubusercontent.com/u/114745848?v=4 avatarUrl: https://avatars.githubusercontent.com/u/114745848?v=4
url: https://github.com/Ponte-Energy-Partners url: https://github.com/Ponte-Energy-Partners
- login: LambdaTest-Inc
avatarUrl: https://avatars.githubusercontent.com/u/171592363?u=96606606a45fa170427206199014f2a5a2a4920b&v=4
url: https://github.com/LambdaTest-Inc
- login: BoostryJP - login: BoostryJP
avatarUrl: https://avatars.githubusercontent.com/u/57932412?v=4 avatarUrl: https://avatars.githubusercontent.com/u/57932412?v=4
url: https://github.com/BoostryJP url: https://github.com/BoostryJP
@ -80,9 +86,6 @@ sponsors:
- login: yasyf - login: yasyf
avatarUrl: https://avatars.githubusercontent.com/u/709645?u=f36736b3c6a85f578886ecc42a740e7b436e7a01&v=4 avatarUrl: https://avatars.githubusercontent.com/u/709645?u=f36736b3c6a85f578886ecc42a740e7b436e7a01&v=4
url: https://github.com/yasyf url: https://github.com/yasyf
- - login: genzou9201
avatarUrl: https://avatars.githubusercontent.com/u/42960762?u=1ca6c18c59e8b327ae584c545b72de31ebc05275&v=4
url: https://github.com/genzou9201
- - login: primer-io - - login: primer-io
avatarUrl: https://avatars.githubusercontent.com/u/62146168?v=4 avatarUrl: https://avatars.githubusercontent.com/u/62146168?v=4
url: https://github.com/primer-io url: https://github.com/primer-io
@ -98,24 +101,18 @@ sponsors:
- - login: samuelcolvin - - login: samuelcolvin
avatarUrl: https://avatars.githubusercontent.com/u/4039449?u=42eb3b833047c8c4b4f647a031eaef148c16d93f&v=4 avatarUrl: https://avatars.githubusercontent.com/u/4039449?u=42eb3b833047c8c4b4f647a031eaef148c16d93f&v=4
url: https://github.com/samuelcolvin url: https://github.com/samuelcolvin
- login: ProteinQure - login: vincentkoc
avatarUrl: https://avatars.githubusercontent.com/u/33707203?v=4 avatarUrl: https://avatars.githubusercontent.com/u/25068?u=fbd5b2d51142daa4bdbc21e21953a3b8b8188a4a&v=4
url: https://github.com/ProteinQure url: https://github.com/vincentkoc
- login: ddilidili - login: ddilidili
avatarUrl: https://avatars.githubusercontent.com/u/42176885?u=c0a849dde06987434653197b5f638d3deb55fc6c&v=4 avatarUrl: https://avatars.githubusercontent.com/u/42176885?u=c0a849dde06987434653197b5f638d3deb55fc6c&v=4
url: https://github.com/ddilidili url: https://github.com/ddilidili
- login: otosky - login: otosky
avatarUrl: https://avatars.githubusercontent.com/u/42260747?u=69d089387c743d89427aa4ad8740cfb34045a9e0&v=4 avatarUrl: https://avatars.githubusercontent.com/u/42260747?u=69d089387c743d89427aa4ad8740cfb34045a9e0&v=4
url: https://github.com/otosky url: https://github.com/otosky
- login: khadrawy - login: ramonalmeidam
avatarUrl: https://avatars.githubusercontent.com/u/13686061?u=59f25ef42ecf04c22657aac4238ce0e2d3d30304&v=4 avatarUrl: https://avatars.githubusercontent.com/u/45269580?u=3358750b3a5854d7c3ed77aaca7dd20a0f529d32&v=4
url: https://github.com/khadrawy 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 - login: sepsi77
avatarUrl: https://avatars.githubusercontent.com/u/18682303?v=4 avatarUrl: https://avatars.githubusercontent.com/u/18682303?v=4
url: https://github.com/sepsi77 url: https://github.com/sepsi77
@ -140,11 +137,17 @@ sponsors:
- login: Leay15 - login: Leay15
avatarUrl: https://avatars.githubusercontent.com/u/32212558?u=c4aa9c1737e515959382a5515381757b1fd86c53&v=4 avatarUrl: https://avatars.githubusercontent.com/u/32212558?u=c4aa9c1737e515959382a5515381757b1fd86c53&v=4
url: https://github.com/Leay15 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 - login: ygorpontelo
avatarUrl: https://avatars.githubusercontent.com/u/32963605?u=35f7103f9c4c4c2589ae5737ee882e9375ef072e&v=4 avatarUrl: https://avatars.githubusercontent.com/u/32963605?u=35f7103f9c4c4c2589ae5737ee882e9375ef072e&v=4
url: https://github.com/ygorpontelo url: https://github.com/ygorpontelo
- login: ProteinQure
avatarUrl: https://avatars.githubusercontent.com/u/33707203?v=4
url: https://github.com/ProteinQure
- login: chickenandstats - login: chickenandstats
avatarUrl: https://avatars.githubusercontent.com/u/79477966?v=4 avatarUrl: https://avatars.githubusercontent.com/u/79477966?u=ae2b894aa954070db1d7830dab99b49eba4e4567&v=4
url: https://github.com/chickenandstats url: https://github.com/chickenandstats
- login: kaoru0310 - login: kaoru0310
avatarUrl: https://avatars.githubusercontent.com/u/80977929?u=1b61d10142b490e56af932ddf08a390fae8ee94f&v=4 avatarUrl: https://avatars.githubusercontent.com/u/80977929?u=1b61d10142b490e56af932ddf08a390fae8ee94f&v=4
@ -164,12 +167,6 @@ sponsors:
- login: logic-automation - login: logic-automation
avatarUrl: https://avatars.githubusercontent.com/u/144732884?v=4 avatarUrl: https://avatars.githubusercontent.com/u/144732884?v=4
url: https://github.com/logic-automation url: https://github.com/logic-automation
- login: Torqsight-Labs
avatarUrl: https://avatars.githubusercontent.com/u/169598176?v=4
url: https://github.com/Torqsight-Labs
- login: ramonalmeidam
avatarUrl: https://avatars.githubusercontent.com/u/45269580?u=3358750b3a5854d7c3ed77aaca7dd20a0f529d32&v=4
url: https://github.com/ramonalmeidam
- login: roboflow - login: roboflow
avatarUrl: https://avatars.githubusercontent.com/u/53104118?v=4 avatarUrl: https://avatars.githubusercontent.com/u/53104118?v=4
url: https://github.com/roboflow url: https://github.com/roboflow
@ -185,12 +182,6 @@ sponsors:
- login: patricioperezv - login: patricioperezv
avatarUrl: https://avatars.githubusercontent.com/u/73832292?u=5f471f156e19ee7920e62ae0f4a47b95580e61cf&v=4 avatarUrl: https://avatars.githubusercontent.com/u/73832292?u=5f471f156e19ee7920e62ae0f4a47b95580e61cf&v=4
url: https://github.com/patricioperezv url: https://github.com/patricioperezv
- login: mintuhouse
avatarUrl: https://avatars.githubusercontent.com/u/769950?u=ecfbd79a97d33177e0d093ddb088283cf7fe8444&v=4
url: https://github.com/mintuhouse
- login: tcsmith
avatarUrl: https://avatars.githubusercontent.com/u/989034?u=7d8d741552b3279e8f4d3878679823a705a46f8f&v=4
url: https://github.com/tcsmith
- login: dodo5522 - login: dodo5522
avatarUrl: https://avatars.githubusercontent.com/u/1362607?u=9bf1e0e520cccc547c046610c468ce6115bbcf9f&v=4 avatarUrl: https://avatars.githubusercontent.com/u/1362607?u=9bf1e0e520cccc547c046610c468ce6115bbcf9f&v=4
url: https://github.com/dodo5522 url: https://github.com/dodo5522
@ -218,9 +209,15 @@ sponsors:
- login: anomaly - login: anomaly
avatarUrl: https://avatars.githubusercontent.com/u/3654837?v=4 avatarUrl: https://avatars.githubusercontent.com/u/3654837?v=4
url: https://github.com/anomaly url: https://github.com/anomaly
- login: vincentkoc - login: gorhack
avatarUrl: https://avatars.githubusercontent.com/u/25068?u=fbd5b2d51142daa4bdbc21e21953a3b8b8188a4a&v=4 avatarUrl: https://avatars.githubusercontent.com/u/4141690?u=ec119ebc4bdf00a7bc84657a71aa17834f4f27f3&v=4
url: https://github.com/vincentkoc url: https://github.com/gorhack
- login: Ryandaydev
avatarUrl: https://avatars.githubusercontent.com/u/4292423?u=48f68868db8886fce31a1d802c1003914c6cd7c6&v=4
url: https://github.com/Ryandaydev
- login: jaredtrog
avatarUrl: https://avatars.githubusercontent.com/u/4381365?v=4
url: https://github.com/jaredtrog
- login: jstanden - login: jstanden
avatarUrl: https://avatars.githubusercontent.com/u/63288?u=c3658d57d2862c607a0e19c2101c3c51876e36ad&v=4 avatarUrl: https://avatars.githubusercontent.com/u/63288?u=c3658d57d2862c607a0e19c2101c3c51876e36ad&v=4
url: https://github.com/jstanden url: https://github.com/jstanden
@ -251,12 +248,12 @@ sponsors:
- login: falkben - login: falkben
avatarUrl: https://avatars.githubusercontent.com/u/653031?u=ad9838e089058c9e5a0bab94c0eec7cc181e0cd0&v=4 avatarUrl: https://avatars.githubusercontent.com/u/653031?u=ad9838e089058c9e5a0bab94c0eec7cc181e0cd0&v=4
url: https://github.com/falkben url: https://github.com/falkben
- login: mintuhouse
avatarUrl: https://avatars.githubusercontent.com/u/769950?u=ecfbd79a97d33177e0d093ddb088283cf7fe8444&v=4
url: https://github.com/mintuhouse
- login: TrevorBenson - login: TrevorBenson
avatarUrl: https://avatars.githubusercontent.com/u/9167887?u=dccbea3327a57750923333d8ebf1a0b3f1948949&v=4 avatarUrl: https://avatars.githubusercontent.com/u/9167887?u=dccbea3327a57750923333d8ebf1a0b3f1948949&v=4
url: https://github.com/TrevorBenson url: https://github.com/TrevorBenson
- login: kaangiray26
avatarUrl: https://avatars.githubusercontent.com/u/11297495?u=e85327a77db45906d44f3ff06dd7f3303c644096&v=4
url: https://github.com/kaangiray26
- login: wdwinslow - login: wdwinslow
avatarUrl: https://avatars.githubusercontent.com/u/11562137?u=dc01daafb354135603a263729e3d26d939c0c452&v=4 avatarUrl: https://avatars.githubusercontent.com/u/11562137?u=dc01daafb354135603a263729e3d26d939c0c452&v=4
url: https://github.com/wdwinslow url: https://github.com/wdwinslow
@ -272,21 +269,18 @@ sponsors:
- login: dannywade - login: dannywade
avatarUrl: https://avatars.githubusercontent.com/u/13680237?u=418ee985bd41577b20fde81417fb2d901e875e8a&v=4 avatarUrl: https://avatars.githubusercontent.com/u/13680237?u=418ee985bd41577b20fde81417fb2d901e875e8a&v=4
url: https://github.com/dannywade url: https://github.com/dannywade
- login: gorhack - login: khadrawy
avatarUrl: https://avatars.githubusercontent.com/u/4141690?u=ec119ebc4bdf00a7bc84657a71aa17834f4f27f3&v=4 avatarUrl: https://avatars.githubusercontent.com/u/13686061?u=59f25ef42ecf04c22657aac4238ce0e2d3d30304&v=4
url: https://github.com/gorhack url: https://github.com/khadrawy
- login: Ryandaydev - login: mjohnsey
avatarUrl: https://avatars.githubusercontent.com/u/4292423?u=48f68868db8886fce31a1d802c1003914c6cd7c6&v=4 avatarUrl: https://avatars.githubusercontent.com/u/16784016?u=38fad2e6b411244560b3af99c5f5a4751bc81865&v=4
url: https://github.com/Ryandaydev url: https://github.com/mjohnsey
- login: jaredtrog - login: ashi-agrawal
avatarUrl: https://avatars.githubusercontent.com/u/4381365?v=4 avatarUrl: https://avatars.githubusercontent.com/u/17105294?u=99c7a854035e5398d8e7b674f2d42baae6c957f8&v=4
url: https://github.com/jaredtrog url: https://github.com/ashi-agrawal
- login: oliverxchen - login: oliverxchen
avatarUrl: https://avatars.githubusercontent.com/u/4471774?u=534191f25e32eeaadda22dfab4b0a428733d5489&v=4 avatarUrl: https://avatars.githubusercontent.com/u/4471774?u=534191f25e32eeaadda22dfab4b0a428733d5489&v=4
url: https://github.com/oliverxchen url: https://github.com/oliverxchen
- login: ennui93
avatarUrl: https://avatars.githubusercontent.com/u/5300907?u=5b5452725ddb391b2caaebf34e05aba873591c3a&v=4
url: https://github.com/ennui93
- login: ternaus - login: ternaus
avatarUrl: https://avatars.githubusercontent.com/u/5481618?u=513a26b02a39e7a28d587cd37c6cc877ea368e6e&v=4 avatarUrl: https://avatars.githubusercontent.com/u/5481618?u=513a26b02a39e7a28d587cd37c6cc877ea368e6e&v=4
url: https://github.com/ternaus url: https://github.com/ternaus
@ -308,9 +302,6 @@ sponsors:
- - login: pawamoy - - login: pawamoy
avatarUrl: https://avatars.githubusercontent.com/u/3999221?u=b030e4c89df2f3a36bc4710b925bdeb6745c9856&v=4 avatarUrl: https://avatars.githubusercontent.com/u/3999221?u=b030e4c89df2f3a36bc4710b925bdeb6745c9856&v=4
url: https://github.com/pawamoy url: https://github.com/pawamoy
- login: engineerjoe440
avatarUrl: https://avatars.githubusercontent.com/u/33275230?u=eb223cad27017bb1e936ee9b429b450d092d0236&v=4
url: https://github.com/engineerjoe440
- login: bnkc - login: bnkc
avatarUrl: https://avatars.githubusercontent.com/u/34930566?u=db5e6f4f87836cad26c2aa90ce390ce49041c5a9&v=4 avatarUrl: https://avatars.githubusercontent.com/u/34930566?u=db5e6f4f87836cad26c2aa90ce390ce49041c5a9&v=4
url: https://github.com/bnkc url: https://github.com/bnkc
@ -323,15 +314,12 @@ sponsors:
- login: mobyw - login: mobyw
avatarUrl: https://avatars.githubusercontent.com/u/44370805?v=4 avatarUrl: https://avatars.githubusercontent.com/u/44370805?v=4
url: https://github.com/mobyw url: https://github.com/mobyw
- login: PelicanQ - login: ArtyomVancyan
avatarUrl: https://avatars.githubusercontent.com/u/77930606?v=4 avatarUrl: https://avatars.githubusercontent.com/u/44609997?v=4
url: https://github.com/PelicanQ url: https://github.com/ArtyomVancyan
- login: TheR1D - login: caviri
avatarUrl: https://avatars.githubusercontent.com/u/16740832?u=b0dfdbdb27b79729430c71c6128962f77b7b53f7&v=4 avatarUrl: https://avatars.githubusercontent.com/u/45425937?u=4e14bd64282bad8f385eafbdb004b5a279366d6e&v=4
url: https://github.com/TheR1D 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 - login: SebTota
avatarUrl: https://avatars.githubusercontent.com/u/25122511?v=4 avatarUrl: https://avatars.githubusercontent.com/u/25122511?v=4
url: https://github.com/SebTota url: https://github.com/SebTota
@ -350,12 +338,9 @@ sponsors:
- login: dvlpjrs - login: dvlpjrs
avatarUrl: https://avatars.githubusercontent.com/u/32254642?u=fbd6ad0324d4f1eb6231cf775be1c7bd4404e961&v=4 avatarUrl: https://avatars.githubusercontent.com/u/32254642?u=fbd6ad0324d4f1eb6231cf775be1c7bd4404e961&v=4
url: https://github.com/dvlpjrs url: https://github.com/dvlpjrs
- login: ArtyomVancyan - login: engineerjoe440
avatarUrl: https://avatars.githubusercontent.com/u/44609997?v=4 avatarUrl: https://avatars.githubusercontent.com/u/33275230?u=eb223cad27017bb1e936ee9b429b450d092d0236&v=4
url: https://github.com/ArtyomVancyan 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 - login: hgalytoby
avatarUrl: https://avatars.githubusercontent.com/u/50397689?u=62c7ff3519858423579676cd0efbd7e3f1ffe63a&v=4 avatarUrl: https://avatars.githubusercontent.com/u/50397689?u=62c7ff3519858423579676cd0efbd7e3f1ffe63a&v=4
url: https://github.com/hgalytoby url: https://github.com/hgalytoby
@ -368,9 +353,9 @@ sponsors:
- login: PunRabbit - login: PunRabbit
avatarUrl: https://avatars.githubusercontent.com/u/70463212?u=1a835cfbc99295a60c8282f6aa6199d1b42241a5&v=4 avatarUrl: https://avatars.githubusercontent.com/u/70463212?u=1a835cfbc99295a60c8282f6aa6199d1b42241a5&v=4
url: https://github.com/PunRabbit url: https://github.com/PunRabbit
- login: tochikuji - login: PelicanQ
avatarUrl: https://avatars.githubusercontent.com/u/851759?v=4 avatarUrl: https://avatars.githubusercontent.com/u/77930606?v=4
url: https://github.com/tochikuji url: https://github.com/PelicanQ
- login: browniebroke - login: browniebroke
avatarUrl: https://avatars.githubusercontent.com/u/861044?u=5abfca5588f3e906b31583d7ee62f6de4b68aa24&v=4 avatarUrl: https://avatars.githubusercontent.com/u/861044?u=5abfca5588f3e906b31583d7ee62f6de4b68aa24&v=4
url: https://github.com/browniebroke url: https://github.com/browniebroke
@ -389,9 +374,6 @@ sponsors:
- login: Alisa-lisa - login: Alisa-lisa
avatarUrl: https://avatars.githubusercontent.com/u/4137964?u=e7e393504f554f4ff15863a1e01a5746863ef9ce&v=4 avatarUrl: https://avatars.githubusercontent.com/u/4137964?u=e7e393504f554f4ff15863a1e01a5746863ef9ce&v=4
url: https://github.com/Alisa-lisa url: https://github.com/Alisa-lisa
- login: hcristea
avatarUrl: https://avatars.githubusercontent.com/u/7814406?u=61d7a4fcf846983a4606788eac25e1c6c1209ba8&v=4
url: https://github.com/hcristea
- login: ddanier - login: ddanier
avatarUrl: https://avatars.githubusercontent.com/u/113563?u=ed1dc79de72f93bd78581f88ebc6952b62f472da&v=4 avatarUrl: https://avatars.githubusercontent.com/u/113563?u=ed1dc79de72f93bd78581f88ebc6952b62f472da&v=4
url: https://github.com/ddanier url: https://github.com/ddanier
@ -404,15 +386,9 @@ sponsors:
- login: ceb10n - login: ceb10n
avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4 avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
url: https://github.com/ceb10n url: https://github.com/ceb10n
- login: eteq - login: tochikuji
avatarUrl: https://avatars.githubusercontent.com/u/346587?v=4 avatarUrl: https://avatars.githubusercontent.com/u/851759?v=4
url: https://github.com/eteq url: https://github.com/tochikuji
- login: securancy
avatarUrl: https://avatars.githubusercontent.com/u/606673?v=4
url: https://github.com/securancy
- login: moonape1226
avatarUrl: https://avatars.githubusercontent.com/u/8532038?u=d9f8b855a429fff9397c3833c2ff83849ebf989d&v=4
url: https://github.com/moonape1226
- login: msehnout - login: msehnout
avatarUrl: https://avatars.githubusercontent.com/u/9369632?u=8c988f1b008a3f601385a3616f9327820f66e3a5&v=4 avatarUrl: https://avatars.githubusercontent.com/u/9369632?u=8c988f1b008a3f601385a3616f9327820f66e3a5&v=4
url: https://github.com/msehnout url: https://github.com/msehnout
@ -420,7 +396,7 @@ sponsors:
avatarUrl: https://avatars.githubusercontent.com/u/9462045?u=a80a7bb349555b277645632ed66639ff43400614&v=4 avatarUrl: https://avatars.githubusercontent.com/u/9462045?u=a80a7bb349555b277645632ed66639ff43400614&v=4
url: https://github.com/xncbf url: https://github.com/xncbf
- login: DMantis - login: DMantis
avatarUrl: https://avatars.githubusercontent.com/u/9536869?v=4 avatarUrl: https://avatars.githubusercontent.com/u/9536869?u=652dd0d49717803c0cbcbf44f7740e53cf2d4892&v=4
url: https://github.com/DMantis url: https://github.com/DMantis
- login: hard-coders - login: hard-coders
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4 avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
@ -434,18 +410,18 @@ sponsors:
- login: pheanex - login: pheanex
avatarUrl: https://avatars.githubusercontent.com/u/10408624?u=5b6bab6ee174aa6e991333e06eb29f628741013d&v=4 avatarUrl: https://avatars.githubusercontent.com/u/10408624?u=5b6bab6ee174aa6e991333e06eb29f628741013d&v=4
url: https://github.com/pheanex url: https://github.com/pheanex
- login: dzoladz
avatarUrl: https://avatars.githubusercontent.com/u/10561752?u=5ee314d54aa79592c18566827ad8914debd5630d&v=4
url: https://github.com/dzoladz
- login: Zuzah - login: Zuzah
avatarUrl: https://avatars.githubusercontent.com/u/10934846?u=1ef43e075ddc87bd1178372bf4d95ee6175cae27&v=4 avatarUrl: https://avatars.githubusercontent.com/u/10934846?u=1ef43e075ddc87bd1178372bf4d95ee6175cae27&v=4
url: https://github.com/Zuzah url: https://github.com/Zuzah
- login: artempronevskiy - login: artempronevskiy
avatarUrl: https://avatars.githubusercontent.com/u/12235104?u=03df6e1e55c9c6fe5d230adabb8dd7d43d8bbe8f&v=4 avatarUrl: https://avatars.githubusercontent.com/u/12235104?u=03df6e1e55c9c6fe5d230adabb8dd7d43d8bbe8f&v=4
url: https://github.com/artempronevskiy url: https://github.com/artempronevskiy
- login: Graeme22 - login: TheR1D
avatarUrl: https://avatars.githubusercontent.com/u/4185684?u=498182a42300d7bcd4de1215190cb17eb501136c&v=4 avatarUrl: https://avatars.githubusercontent.com/u/16740832?u=b0dfdbdb27b79729430c71c6128962f77b7b53f7&v=4
url: https://github.com/Graeme22 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 - login: danielunderwood
avatarUrl: https://avatars.githubusercontent.com/u/4472301?v=4 avatarUrl: https://avatars.githubusercontent.com/u/4472301?v=4
url: https://github.com/danielunderwood url: https://github.com/danielunderwood
@ -470,6 +446,12 @@ sponsors:
- login: harsh183 - login: harsh183
avatarUrl: https://avatars.githubusercontent.com/u/7780198?v=4 avatarUrl: https://avatars.githubusercontent.com/u/7780198?v=4
url: https://github.com/harsh183 url: https://github.com/harsh183
- login: hcristea
avatarUrl: https://avatars.githubusercontent.com/u/7814406?u=19092923a4ea5b338567961c8270b9206a6d81bb&v=4
url: https://github.com/hcristea
- login: moonape1226
avatarUrl: https://avatars.githubusercontent.com/u/8532038?u=d9f8b855a429fff9397c3833c2ff83849ebf989d&v=4
url: https://github.com/moonape1226
- - login: larsyngvelundin - - login: larsyngvelundin
avatarUrl: https://avatars.githubusercontent.com/u/34173819?u=74958599695bf83ac9f1addd935a51548a10c6b0&v=4 avatarUrl: https://avatars.githubusercontent.com/u/34173819?u=74958599695bf83ac9f1addd935a51548a10c6b0&v=4
url: https://github.com/larsyngvelundin url: https://github.com/larsyngvelundin
@ -479,6 +461,9 @@ sponsors:
- login: rwxd - login: rwxd
avatarUrl: https://avatars.githubusercontent.com/u/40308458?u=cd04a39e3655923be4f25c2ba8a5a07b3da3230a&v=4 avatarUrl: https://avatars.githubusercontent.com/u/40308458?u=cd04a39e3655923be4f25c2ba8a5a07b3da3230a&v=4
url: https://github.com/rwxd url: https://github.com/rwxd
- login: morzan1001
avatarUrl: https://avatars.githubusercontent.com/u/47593005?u=c30ab7230f82a12a9b938dcb54f84a996931409a&v=4
url: https://github.com/morzan1001
- login: sadikkuzu - login: sadikkuzu
avatarUrl: https://avatars.githubusercontent.com/u/23168063?u=d179c06bb9f65c4167fcab118526819f8e0dac17&v=4 avatarUrl: https://avatars.githubusercontent.com/u/23168063?u=d179c06bb9f65c4167fcab118526819f8e0dac17&v=4
url: https://github.com/sadikkuzu url: https://github.com/sadikkuzu
@ -488,12 +473,12 @@ sponsors:
- login: FabulousCodingFox - login: FabulousCodingFox
avatarUrl: https://avatars.githubusercontent.com/u/78906517?u=924a27cbee3db7e0ece5cc1509921402e1445e74&v=4 avatarUrl: https://avatars.githubusercontent.com/u/78906517?u=924a27cbee3db7e0ece5cc1509921402e1445e74&v=4
url: https://github.com/FabulousCodingFox url: https://github.com/FabulousCodingFox
- login: gateremark - login: anqorithm
avatarUrl: https://avatars.githubusercontent.com/u/91592218?u=969314eb2cfb035196f4d19499ec6f5050d7583a&v=4 avatarUrl: https://avatars.githubusercontent.com/u/61029571?u=468256fa4e2d9ce2870b608299724bebb7a33f18&v=4
url: https://github.com/gateremark url: https://github.com/anqorithm
- login: morzan1001 - login: Materacl
avatarUrl: https://avatars.githubusercontent.com/u/47593005?u=c30ab7230f82a12a9b938dcb54f84a996931409a&v=4 avatarUrl: https://avatars.githubusercontent.com/u/70155818?u=ae11d084518856127cca483816a91a187e3124ee&v=4
url: https://github.com/morzan1001 url: https://github.com/Materacl
- login: Toothwitch - login: Toothwitch
avatarUrl: https://avatars.githubusercontent.com/u/1710406?u=5eebb23b46cd26e48643b9e5179536cad491c17a&v=4 avatarUrl: https://avatars.githubusercontent.com/u/1710406?u=5eebb23b46cd26e48643b9e5179536cad491c17a&v=4
url: https://github.com/Toothwitch url: https://github.com/Toothwitch

6
docs/en/data/sponsors.yml

@ -58,9 +58,9 @@ bronze:
- url: https://www.exoflare.com/open-source/?utm_source=FastAPI&utm_campaign=open_source - url: https://www.exoflare.com/open-source/?utm_source=FastAPI&utm_campaign=open_source
title: Biosecurity risk assessments made easy. title: Biosecurity risk assessments made easy.
img: https://fastapi.tiangolo.com/img/sponsors/exoflare.png img: https://fastapi.tiangolo.com/img/sponsors/exoflare.png
- url: https://testdriven.io/courses/tdd-fastapi/ # - url: https://testdriven.io/courses/tdd-fastapi/
title: Learn to build high-quality web apps with best practices # title: Learn to build high-quality web apps with best practices
img: https://fastapi.tiangolo.com/img/sponsors/testdriven.svg # img: https://fastapi.tiangolo.com/img/sponsors/testdriven.svg
- url: https://lambdatest.com/?utm_source=fastapi&utm_medium=partner&utm_campaign=sponsor&utm_term=opensource&utm_content=webpage - url: https://lambdatest.com/?utm_source=fastapi&utm_medium=partner&utm_campaign=sponsor&utm_term=opensource&utm_content=webpage
title: LambdaTest, AI-Powered Cloud-based Test Orchestration Platform title: LambdaTest, AI-Powered Cloud-based Test Orchestration Platform
img: https://fastapi.tiangolo.com/img/sponsors/lambdatest.png img: https://fastapi.tiangolo.com/img/sponsors/lambdatest.png

336
docs/en/data/topic_repos.yml

@ -1,86 +1,86 @@
- name: full-stack-fastapi-template - name: full-stack-fastapi-template
html_url: https://github.com/fastapi/full-stack-fastapi-template html_url: https://github.com/fastapi/full-stack-fastapi-template
stars: 29409 stars: 30645
owner_login: fastapi owner_login: fastapi
owner_html_url: https://github.com/fastapi owner_html_url: https://github.com/fastapi
- name: Hello-Python - name: Hello-Python
html_url: https://github.com/mouredev/Hello-Python html_url: https://github.com/mouredev/Hello-Python
stars: 28113 stars: 28690
owner_login: mouredev owner_login: mouredev
owner_html_url: https://github.com/mouredev owner_html_url: https://github.com/mouredev
- name: serve - name: serve
html_url: https://github.com/jina-ai/serve html_url: https://github.com/jina-ai/serve
stars: 21264 stars: 21356
owner_login: jina-ai owner_login: jina-ai
owner_html_url: https://github.com/jina-ai owner_html_url: https://github.com/jina-ai
- name: sqlmodel - name: sqlmodel
html_url: https://github.com/fastapi/sqlmodel html_url: https://github.com/fastapi/sqlmodel
stars: 15109 stars: 15312
owner_login: fastapi owner_login: fastapi
owner_html_url: https://github.com/fastapi owner_html_url: https://github.com/fastapi
- name: HivisionIDPhotos - name: HivisionIDPhotos
html_url: https://github.com/Zeyi-Lin/HivisionIDPhotos html_url: https://github.com/Zeyi-Lin/HivisionIDPhotos
stars: 14564 stars: 14957
owner_login: Zeyi-Lin owner_login: Zeyi-Lin
owner_html_url: https://github.com/Zeyi-Lin owner_html_url: https://github.com/Zeyi-Lin
- name: Douyin_TikTok_Download_API - name: Douyin_TikTok_Download_API
html_url: https://github.com/Evil0ctal/Douyin_TikTok_Download_API html_url: https://github.com/Evil0ctal/Douyin_TikTok_Download_API
stars: 10701 stars: 11192
owner_login: Evil0ctal owner_login: Evil0ctal
owner_html_url: https://github.com/Evil0ctal owner_html_url: https://github.com/Evil0ctal
- name: fastapi-best-practices - name: fastapi-best-practices
html_url: https://github.com/zhanymkanov/fastapi-best-practices html_url: https://github.com/zhanymkanov/fastapi-best-practices
stars: 10180 stars: 10501
owner_login: zhanymkanov owner_login: zhanymkanov
owner_html_url: https://github.com/zhanymkanov owner_html_url: https://github.com/zhanymkanov
- name: awesome-fastapi - name: awesome-fastapi
html_url: https://github.com/mjhea0/awesome-fastapi html_url: https://github.com/mjhea0/awesome-fastapi
stars: 9061 stars: 9193
owner_login: mjhea0 owner_login: mjhea0
owner_html_url: https://github.com/mjhea0 owner_html_url: https://github.com/mjhea0
- name: FastUI - name: FastUI
html_url: https://github.com/pydantic/FastUI html_url: https://github.com/pydantic/FastUI
stars: 8644 stars: 8721
owner_login: pydantic owner_login: pydantic
owner_html_url: https://github.com/pydantic owner_html_url: https://github.com/pydantic
- name: nonebot2 - name: nonebot2
html_url: https://github.com/nonebot/nonebot2 html_url: https://github.com/nonebot/nonebot2
stars: 6312 stars: 6433
owner_login: nonebot owner_login: nonebot
owner_html_url: https://github.com/nonebot owner_html_url: https://github.com/nonebot
- name: serge - name: serge
html_url: https://github.com/serge-chat/serge html_url: https://github.com/serge-chat/serge
stars: 5686 stars: 5699
owner_login: serge-chat owner_login: serge-chat
owner_html_url: https://github.com/serge-chat owner_html_url: https://github.com/serge-chat
- name: FileCodeBox - name: FileCodeBox
html_url: https://github.com/vastsa/FileCodeBox html_url: https://github.com/vastsa/FileCodeBox
stars: 4933 stars: 5534
owner_login: vastsa owner_login: vastsa
owner_html_url: https://github.com/vastsa owner_html_url: https://github.com/vastsa
- name: fastapi-users - name: fastapi-users
html_url: https://github.com/fastapi-users/fastapi-users html_url: https://github.com/fastapi-users/fastapi-users
stars: 4849 stars: 4921
owner_login: fastapi-users owner_login: fastapi-users
owner_html_url: https://github.com/fastapi-users owner_html_url: https://github.com/fastapi-users
- name: polar
html_url: https://github.com/polarsource/polar
stars: 4598
owner_login: polarsource
owner_html_url: https://github.com/polarsource
- name: hatchet - name: hatchet
html_url: https://github.com/hatchet-dev/hatchet html_url: https://github.com/hatchet-dev/hatchet
stars: 4514 stars: 4585
owner_login: hatchet-dev owner_login: hatchet-dev
owner_html_url: https://github.com/hatchet-dev owner_html_url: https://github.com/hatchet-dev
- name: chatgpt-web-share - name: chatgpt-web-share
html_url: https://github.com/chatpire/chatgpt-web-share html_url: https://github.com/chatpire/chatgpt-web-share
stars: 4319 stars: 4318
owner_login: chatpire owner_login: chatpire
owner_html_url: https://github.com/chatpire owner_html_url: https://github.com/chatpire
- name: polar
html_url: https://github.com/polarsource/polar
stars: 4216
owner_login: polarsource
owner_html_url: https://github.com/polarsource
- name: strawberry - name: strawberry
html_url: https://github.com/strawberry-graphql/strawberry html_url: https://github.com/strawberry-graphql/strawberry
stars: 4126 stars: 4180
owner_login: strawberry-graphql owner_login: strawberry-graphql
owner_html_url: https://github.com/strawberry-graphql owner_html_url: https://github.com/strawberry-graphql
- name: atrilabs-engine - name: atrilabs-engine
@ -90,279 +90,284 @@
owner_html_url: https://github.com/Atri-Labs owner_html_url: https://github.com/Atri-Labs
- name: dynaconf - name: dynaconf
html_url: https://github.com/dynaconf/dynaconf html_url: https://github.com/dynaconf/dynaconf
stars: 3874 stars: 3904
owner_login: dynaconf owner_login: dynaconf
owner_html_url: https://github.com/dynaconf owner_html_url: https://github.com/dynaconf
- name: poem - name: poem
html_url: https://github.com/poem-web/poem html_url: https://github.com/poem-web/poem
stars: 3746 stars: 3781
owner_login: poem-web owner_login: poem-web
owner_html_url: https://github.com/poem-web owner_html_url: https://github.com/poem-web
- name: opyrator
html_url: https://github.com/ml-tooling/opyrator
stars: 3117
owner_login: ml-tooling
owner_html_url: https://github.com/ml-tooling
- name: farfalle - name: farfalle
html_url: https://github.com/rashadphz/farfalle html_url: https://github.com/rashadphz/farfalle
stars: 3094 stars: 3190
owner_login: rashadphz owner_login: rashadphz
owner_html_url: https://github.com/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 - name: fastapi-admin
html_url: https://github.com/fastapi-admin/fastapi-admin html_url: https://github.com/fastapi-admin/fastapi-admin
stars: 3040 stars: 3086
owner_login: fastapi-admin owner_login: fastapi-admin
owner_html_url: https://github.com/fastapi-admin owner_html_url: https://github.com/fastapi-admin
- name: docarray - name: docarray
html_url: https://github.com/docarray/docarray html_url: https://github.com/docarray/docarray
stars: 3007 stars: 3021
owner_login: docarray owner_login: docarray
owner_html_url: https://github.com/docarray owner_html_url: https://github.com/docarray
- name: datamodel-code-generator - name: datamodel-code-generator
html_url: https://github.com/koxudaxi/datamodel-code-generator html_url: https://github.com/koxudaxi/datamodel-code-generator
stars: 2914 stars: 2988
owner_login: koxudaxi owner_login: koxudaxi
owner_html_url: https://github.com/koxudaxi owner_html_url: https://github.com/koxudaxi
- name: fastapi-realworld-example-app
html_url: https://github.com/nsidnev/fastapi-realworld-example-app
stars: 2840
owner_login: nsidnev
owner_html_url: https://github.com/nsidnev
- name: LitServe - name: LitServe
html_url: https://github.com/Lightning-AI/LitServe html_url: https://github.com/Lightning-AI/LitServe
stars: 2804 stars: 2863
owner_login: Lightning-AI owner_login: Lightning-AI
owner_html_url: https://github.com/Lightning-AI owner_html_url: https://github.com/Lightning-AI
- name: uvicorn-gunicorn-fastapi-docker - name: fastapi-realworld-example-app
html_url: https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker html_url: https://github.com/nsidnev/fastapi-realworld-example-app
stars: 2730 stars: 2850
owner_login: tiangolo owner_login: nsidnev
owner_html_url: https://github.com/tiangolo owner_html_url: https://github.com/nsidnev
- name: logfire - name: logfire
html_url: https://github.com/pydantic/logfire html_url: https://github.com/pydantic/logfire
stars: 2620 stars: 2757
owner_login: pydantic owner_login: pydantic
owner_html_url: https://github.com/pydantic owner_html_url: https://github.com/pydantic
- name: uvicorn-gunicorn-fastapi-docker
html_url: https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker
stars: 2731
owner_login: tiangolo
owner_html_url: https://github.com/tiangolo
- name: huma - name: huma
html_url: https://github.com/danielgtaylor/huma html_url: https://github.com/danielgtaylor/huma
stars: 2567 stars: 2700
owner_login: danielgtaylor owner_login: danielgtaylor
owner_html_url: https://github.com/danielgtaylor owner_html_url: https://github.com/danielgtaylor
- name: tracecat - name: tracecat
html_url: https://github.com/TracecatHQ/tracecat html_url: https://github.com/TracecatHQ/tracecat
stars: 2494 stars: 2539
owner_login: TracecatHQ owner_login: TracecatHQ
owner_html_url: https://github.com/TracecatHQ owner_html_url: https://github.com/TracecatHQ
- name: best-of-web-python - name: best-of-web-python
html_url: https://github.com/ml-tooling/best-of-web-python html_url: https://github.com/ml-tooling/best-of-web-python
stars: 2433 stars: 2460
owner_login: ml-tooling owner_login: ml-tooling
owner_html_url: https://github.com/ml-tooling owner_html_url: https://github.com/ml-tooling
- name: RasaGPT - name: RasaGPT
html_url: https://github.com/paulpierre/RasaGPT html_url: https://github.com/paulpierre/RasaGPT
stars: 2386 stars: 2401
owner_login: paulpierre owner_login: paulpierre
owner_html_url: https://github.com/paulpierre owner_html_url: https://github.com/paulpierre
- name: fastapi-react - name: fastapi-react
html_url: https://github.com/Buuntu/fastapi-react html_url: https://github.com/Buuntu/fastapi-react
stars: 2293 stars: 2315
owner_login: Buuntu owner_login: Buuntu
owner_html_url: https://github.com/Buuntu owner_html_url: https://github.com/Buuntu
- name: nextpy - name: nextpy
html_url: https://github.com/dot-agent/nextpy html_url: https://github.com/dot-agent/nextpy
stars: 2256 stars: 2266
owner_login: dot-agent owner_login: dot-agent
owner_html_url: https://github.com/dot-agent owner_html_url: https://github.com/dot-agent
- name: 30-Days-of-Python - name: 30-Days-of-Python
html_url: https://github.com/codingforentrepreneurs/30-Days-of-Python html_url: https://github.com/codingforentrepreneurs/30-Days-of-Python
stars: 2155 stars: 2163
owner_login: codingforentrepreneurs owner_login: codingforentrepreneurs
owner_html_url: https://github.com/codingforentrepreneurs owner_html_url: https://github.com/codingforentrepreneurs
- name: FastAPI-template - name: FastAPI-template
html_url: https://github.com/s3rius/FastAPI-template html_url: https://github.com/s3rius/FastAPI-template
stars: 2121 stars: 2156
owner_login: s3rius owner_login: s3rius
owner_html_url: https://github.com/s3rius owner_html_url: https://github.com/s3rius
- name: sqladmin - name: sqladmin
html_url: https://github.com/aminalaee/sqladmin html_url: https://github.com/aminalaee/sqladmin
stars: 2021 stars: 2051
owner_login: aminalaee owner_login: aminalaee
owner_html_url: https://github.com/aminalaee owner_html_url: https://github.com/aminalaee
- name: langserve - name: langserve
html_url: https://github.com/langchain-ai/langserve html_url: https://github.com/langchain-ai/langserve
stars: 2006 stars: 2025
owner_login: langchain-ai owner_login: langchain-ai
owner_html_url: https://github.com/langchain-ai owner_html_url: https://github.com/langchain-ai
- name: fastapi-utils - name: fastapi-utils
html_url: https://github.com/fastapiutils/fastapi-utils html_url: https://github.com/fastapiutils/fastapi-utils
stars: 2002 stars: 2021
owner_login: fastapiutils owner_login: fastapiutils
owner_html_url: https://github.com/fastapiutils owner_html_url: https://github.com/fastapiutils
- name: solara - name: solara
html_url: https://github.com/widgetti/solara html_url: https://github.com/widgetti/solara
stars: 1967 stars: 1980
owner_login: widgetti owner_login: widgetti
owner_html_url: https://github.com/widgetti owner_html_url: https://github.com/widgetti
- name: supabase-py - name: supabase-py
html_url: https://github.com/supabase/supabase-py html_url: https://github.com/supabase/supabase-py
stars: 1848 stars: 1874
owner_login: supabase owner_login: supabase
owner_html_url: https://github.com/supabase owner_html_url: https://github.com/supabase
- name: python-week-2022 - name: python-week-2022
html_url: https://github.com/rochacbruno/python-week-2022 html_url: https://github.com/rochacbruno/python-week-2022
stars: 1832 stars: 1829
owner_login: rochacbruno owner_login: rochacbruno
owner_html_url: https://github.com/rochacbruno owner_html_url: https://github.com/rochacbruno
- name: mangum - name: mangum
html_url: https://github.com/Kludex/mangum html_url: https://github.com/Kludex/mangum
stars: 1789 stars: 1820
owner_login: Kludex owner_login: Kludex
owner_html_url: https://github.com/Kludex owner_html_url: https://github.com/Kludex
- name: Kokoro-FastAPI
html_url: https://github.com/remsky/Kokoro-FastAPI
stars: 1771
owner_login: remsky
owner_html_url: https://github.com/remsky
- name: manage-fastapi - name: manage-fastapi
html_url: https://github.com/ycd/manage-fastapi html_url: https://github.com/ycd/manage-fastapi
stars: 1711 stars: 1719
owner_login: ycd owner_login: ycd
owner_html_url: https://github.com/ycd owner_html_url: https://github.com/ycd
- name: ormar - name: ormar
html_url: https://github.com/collerek/ormar html_url: https://github.com/collerek/ormar
stars: 1701 stars: 1710
owner_login: collerek owner_login: collerek
owner_html_url: https://github.com/collerek owner_html_url: https://github.com/collerek
- name: agentkit - name: agentkit
html_url: https://github.com/BCG-X-Official/agentkit html_url: https://github.com/BCG-X-Official/agentkit
stars: 1630 stars: 1658
owner_login: BCG-X-Official owner_login: BCG-X-Official
owner_html_url: https://github.com/BCG-X-Official owner_html_url: https://github.com/BCG-X-Official
- name: langchain-serve - name: langchain-serve
html_url: https://github.com/jina-ai/langchain-serve html_url: https://github.com/jina-ai/langchain-serve
stars: 1617 stars: 1618
owner_login: jina-ai owner_login: jina-ai
owner_html_url: https://github.com/jina-ai owner_html_url: https://github.com/jina-ai
- name: termpair - name: termpair
html_url: https://github.com/cs01/termpair html_url: https://github.com/cs01/termpair
stars: 1612 stars: 1611
owner_login: cs01 owner_login: cs01
owner_html_url: https://github.com/cs01 owner_html_url: https://github.com/cs01
- name: coronavirus-tracker-api - name: coronavirus-tracker-api
html_url: https://github.com/ExpDev07/coronavirus-tracker-api html_url: https://github.com/ExpDev07/coronavirus-tracker-api
stars: 1590 stars: 1588
owner_login: ExpDev07 owner_login: ExpDev07
owner_html_url: https://github.com/ExpDev07 owner_html_url: https://github.com/ExpDev07
- name: piccolo - name: piccolo
html_url: https://github.com/piccolo-orm/piccolo html_url: https://github.com/piccolo-orm/piccolo
stars: 1519 stars: 1546
owner_login: piccolo-orm owner_login: piccolo-orm
owner_html_url: https://github.com/piccolo-orm owner_html_url: https://github.com/piccolo-orm
- name: fastapi-crudrouter
html_url: https://github.com/awtkns/fastapi-crudrouter
stars: 1449
owner_login: awtkns
owner_html_url: https://github.com/awtkns
- name: fastapi-cache - name: fastapi-cache
html_url: https://github.com/long2ice/fastapi-cache html_url: https://github.com/long2ice/fastapi-cache
stars: 1447 stars: 1478
owner_login: long2ice owner_login: long2ice
owner_html_url: https://github.com/long2ice owner_html_url: https://github.com/long2ice
- name: openapi-python-client - name: openapi-python-client
html_url: https://github.com/openapi-generators/openapi-python-client html_url: https://github.com/openapi-generators/openapi-python-client
stars: 1434 stars: 1467
owner_login: openapi-generators owner_login: openapi-generators
owner_html_url: https://github.com/openapi-generators owner_html_url: https://github.com/openapi-generators
- name: fastapi-crudrouter
html_url: https://github.com/awtkns/fastapi-crudrouter
stars: 1462
owner_login: awtkns
owner_html_url: https://github.com/awtkns
- name: awesome-fastapi-projects - name: awesome-fastapi-projects
html_url: https://github.com/Kludex/awesome-fastapi-projects html_url: https://github.com/Kludex/awesome-fastapi-projects
stars: 1398 stars: 1418
owner_login: Kludex owner_login: Kludex
owner_html_url: https://github.com/Kludex owner_html_url: https://github.com/Kludex
- name: awesome-python-resources - name: awesome-python-resources
html_url: https://github.com/DjangoEx/awesome-python-resources html_url: https://github.com/DjangoEx/awesome-python-resources
stars: 1380 stars: 1383
owner_login: DjangoEx owner_login: DjangoEx
owner_html_url: https://github.com/DjangoEx owner_html_url: https://github.com/DjangoEx
- name: slowapi
html_url: https://github.com/laurentS/slowapi
stars: 1363
owner_login: laurentS
owner_html_url: https://github.com/laurentS
- name: budgetml - name: budgetml
html_url: https://github.com/ebhy/budgetml html_url: https://github.com/ebhy/budgetml
stars: 1344 stars: 1344
owner_login: ebhy owner_login: ebhy
owner_html_url: https://github.com/ebhy owner_html_url: https://github.com/ebhy
- name: slowapi
html_url: https://github.com/laurentS/slowapi
stars: 1339
owner_login: laurentS
owner_html_url: https://github.com/laurentS
- name: fastapi-pagination - name: fastapi-pagination
html_url: https://github.com/uriyyo/fastapi-pagination html_url: https://github.com/uriyyo/fastapi-pagination
stars: 1263 stars: 1284
owner_login: uriyyo owner_login: uriyyo
owner_html_url: https://github.com/uriyyo owner_html_url: https://github.com/uriyyo
- name: fastapi-boilerplate - name: fastapi-boilerplate
html_url: https://github.com/teamhide/fastapi-boilerplate html_url: https://github.com/teamhide/fastapi-boilerplate
stars: 1206 stars: 1234
owner_login: teamhide owner_login: teamhide
owner_html_url: https://github.com/teamhide owner_html_url: https://github.com/teamhide
- name: fastapi-tutorial - name: fastapi-tutorial
html_url: https://github.com/liaogx/fastapi-tutorial html_url: https://github.com/liaogx/fastapi-tutorial
stars: 1178 stars: 1181
owner_login: liaogx owner_login: liaogx
owner_html_url: https://github.com/liaogx owner_html_url: https://github.com/liaogx
- name: fastapi-amis-admin - name: fastapi-amis-admin
html_url: https://github.com/amisadmin/fastapi-amis-admin html_url: https://github.com/amisadmin/fastapi-amis-admin
stars: 1142 stars: 1164
owner_login: amisadmin owner_login: amisadmin
owner_html_url: https://github.com/amisadmin owner_html_url: https://github.com/amisadmin
- name: fastapi-code-generator - name: fastapi-code-generator
html_url: https://github.com/koxudaxi/fastapi-code-generator html_url: https://github.com/koxudaxi/fastapi-code-generator
stars: 1119 stars: 1132
owner_login: koxudaxi owner_login: koxudaxi
owner_html_url: https://github.com/koxudaxi owner_html_url: https://github.com/koxudaxi
- name: bolt-python - name: bolt-python
html_url: https://github.com/slackapi/bolt-python html_url: https://github.com/slackapi/bolt-python
stars: 1116 stars: 1130
owner_login: slackapi owner_login: slackapi
owner_html_url: https://github.com/slackapi owner_html_url: https://github.com/slackapi
- name: odmantic
html_url: https://github.com/art049/odmantic
stars: 1096
owner_login: art049
owner_html_url: https://github.com/art049
- name: langchain-extract - name: langchain-extract
html_url: https://github.com/langchain-ai/langchain-extract html_url: https://github.com/langchain-ai/langchain-extract
stars: 1093 stars: 1110
owner_login: langchain-ai owner_login: langchain-ai
owner_html_url: https://github.com/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 - name: fastapi_production_template
html_url: https://github.com/zhanymkanov/fastapi_production_template html_url: https://github.com/zhanymkanov/fastapi_production_template
stars: 1078 stars: 1093
owner_login: zhanymkanov owner_login: zhanymkanov
owner_html_url: https://github.com/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 - name: fastapi-alembic-sqlmodel-async
html_url: https://github.com/jonra1993/fastapi-alembic-sqlmodel-async html_url: https://github.com/jonra1993/fastapi-alembic-sqlmodel-async
stars: 1055 stars: 1063
owner_login: jonra1993 owner_login: jonra1993
owner_html_url: https://github.com/jonra1993 owner_html_url: https://github.com/jonra1993
- name: Kokoro-FastAPI
html_url: https://github.com/remsky/Kokoro-FastAPI
stars: 1047
owner_login: remsky
owner_html_url: https://github.com/remsky
- name: prometheus-fastapi-instrumentator - name: prometheus-fastapi-instrumentator
html_url: https://github.com/trallnag/prometheus-fastapi-instrumentator html_url: https://github.com/trallnag/prometheus-fastapi-instrumentator
stars: 1036 stars: 1059
owner_login: trallnag owner_login: trallnag
owner_html_url: https://github.com/trallnag owner_html_url: https://github.com/trallnag
- name: SurfSense
html_url: https://github.com/MODSetter/SurfSense
stars: 1018
owner_login: MODSetter
owner_html_url: https://github.com/MODSetter
- name: bedrock-claude-chat - name: bedrock-claude-chat
html_url: https://github.com/aws-samples/bedrock-claude-chat html_url: https://github.com/aws-samples/bedrock-claude-chat
stars: 1010 stars: 1039
owner_login: aws-samples owner_login: aws-samples
owner_html_url: https://github.com/aws-samples owner_html_url: https://github.com/aws-samples
- name: runhouse - name: runhouse
html_url: https://github.com/run-house/runhouse html_url: https://github.com/run-house/runhouse
stars: 1000 stars: 1005
owner_login: run-house owner_login: run-house
owner_html_url: https://github.com/run-house owner_html_url: https://github.com/run-house
- name: vue-fastapi-admin
html_url: https://github.com/mizhexiaoxiao/vue-fastapi-admin
stars: 987
owner_login: mizhexiaoxiao
owner_html_url: https://github.com/mizhexiaoxiao
- name: lanarky - name: lanarky
html_url: https://github.com/ajndkr/lanarky html_url: https://github.com/ajndkr/lanarky
stars: 986 stars: 986
@ -370,126 +375,121 @@
owner_html_url: https://github.com/ajndkr owner_html_url: https://github.com/ajndkr
- name: autollm - name: autollm
html_url: https://github.com/viddexa/autollm html_url: https://github.com/viddexa/autollm
stars: 982 stars: 986
owner_login: viddexa owner_login: viddexa
owner_html_url: https://github.com/viddexa owner_html_url: https://github.com/viddexa
- name: restish - name: restish
html_url: https://github.com/danielgtaylor/restish html_url: https://github.com/danielgtaylor/restish
stars: 970 stars: 984
owner_login: danielgtaylor owner_login: danielgtaylor
owner_html_url: https://github.com/danielgtaylor owner_html_url: https://github.com/danielgtaylor
- name: fastcrud - name: fastcrud
html_url: https://github.com/igorbenav/fastcrud html_url: https://github.com/igorbenav/fastcrud
stars: 929 stars: 964
owner_login: igorbenav owner_login: igorbenav
owner_html_url: https://github.com/igorbenav owner_html_url: https://github.com/igorbenav
- name: secure - name: secure
html_url: https://github.com/TypeError/secure html_url: https://github.com/TypeError/secure
stars: 921 stars: 928
owner_login: TypeError owner_login: TypeError
owner_html_url: https://github.com/TypeError owner_html_url: https://github.com/TypeError
- name: langcorn - name: langcorn
html_url: https://github.com/msoedov/langcorn html_url: https://github.com/msoedov/langcorn
stars: 915 stars: 916
owner_login: msoedov owner_login: msoedov
owner_html_url: https://github.com/msoedov owner_html_url: https://github.com/msoedov
- name: vue-fastapi-admin
html_url: https://github.com/mizhexiaoxiao/vue-fastapi-admin
stars: 915
owner_login: mizhexiaoxiao
owner_html_url: https://github.com/mizhexiaoxiao
- name: energy-forecasting - name: energy-forecasting
html_url: https://github.com/iusztinpaul/energy-forecasting html_url: https://github.com/iusztinpaul/energy-forecasting
stars: 891 stars: 898
owner_login: iusztinpaul owner_login: iusztinpaul
owner_html_url: https://github.com/iusztinpaul owner_html_url: https://github.com/iusztinpaul
- name: authx - name: authx
html_url: https://github.com/yezz123/authx html_url: https://github.com/yezz123/authx
stars: 862 stars: 874
owner_login: yezz123 owner_login: yezz123
owner_html_url: https://github.com/yezz123 owner_html_url: https://github.com/yezz123
- name: titiler - name: titiler
html_url: https://github.com/developmentseed/titiler html_url: https://github.com/developmentseed/titiler
stars: 823 stars: 841
owner_login: developmentseed owner_login: developmentseed
owner_html_url: https://github.com/developmentseed owner_html_url: https://github.com/developmentseed
- name: marker-api
html_url: https://github.com/adithya-s-k/marker-api
stars: 798
owner_login: adithya-s-k
owner_html_url: https://github.com/adithya-s-k
- name: FastAPI-boilerplate - name: FastAPI-boilerplate
html_url: https://github.com/igorbenav/FastAPI-boilerplate html_url: https://github.com/igorbenav/FastAPI-boilerplate
stars: 774 stars: 820
owner_login: igorbenav owner_login: igorbenav
owner_html_url: https://github.com/igorbenav owner_html_url: https://github.com/igorbenav
- name: marker-api
html_url: https://github.com/adithya-s-k/marker-api
stars: 813
owner_login: adithya-s-k
owner_html_url: https://github.com/adithya-s-k
- name: fastapi_best_architecture - name: fastapi_best_architecture
html_url: https://github.com/fastapi-practices/fastapi_best_architecture html_url: https://github.com/fastapi-practices/fastapi_best_architecture
stars: 766 stars: 802
owner_login: fastapi-practices owner_login: fastapi-practices
owner_html_url: https://github.com/fastapi-practices owner_html_url: https://github.com/fastapi-practices
- name: fastapi-mail
html_url: https://github.com/sabuhish/fastapi-mail
stars: 735
owner_login: sabuhish
owner_html_url: https://github.com/sabuhish
- name: annotated-py-projects
html_url: https://github.com/hhstore/annotated-py-projects
stars: 725
owner_login: hhstore
owner_html_url: https://github.com/hhstore
- name: fastapi-do-zero - name: fastapi-do-zero
html_url: https://github.com/dunossauro/fastapi-do-zero html_url: https://github.com/dunossauro/fastapi-do-zero
stars: 723 stars: 745
owner_login: dunossauro owner_login: dunossauro
owner_html_url: https://github.com/dunossauro owner_html_url: https://github.com/dunossauro
- name: lccn_predictor - name: fastapi-mail
html_url: https://github.com/baoliay2008/lccn_predictor html_url: https://github.com/sabuhish/fastapi-mail
stars: 718 stars: 744
owner_login: baoliay2008 owner_login: sabuhish
owner_html_url: https://github.com/baoliay2008 owner_html_url: https://github.com/sabuhish
- name: fastapi-observability - name: fastapi-observability
html_url: https://github.com/blueswen/fastapi-observability html_url: https://github.com/blueswen/fastapi-observability
stars: 718 stars: 743
owner_login: blueswen owner_login: blueswen
owner_html_url: https://github.com/blueswen owner_html_url: https://github.com/blueswen
- name: chatGPT-web - name: lccn_predictor
html_url: https://github.com/mic1on/chatGPT-web html_url: https://github.com/baoliay2008/lccn_predictor
stars: 708 stars: 741
owner_login: mic1on owner_login: baoliay2008
owner_html_url: https://github.com/mic1on 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 - name: learn-generative-ai
html_url: https://github.com/panaverse/learn-generative-ai html_url: https://github.com/panaverse/learn-generative-ai
stars: 701 stars: 714
owner_login: panaverse owner_login: panaverse
owner_html_url: https://github.com/panaverse owner_html_url: https://github.com/panaverse
- name: linbing
html_url: https://github.com/taomujian/linbing
stars: 700
owner_login: taomujian
owner_html_url: https://github.com/taomujian
- name: FastAPI-Backend-Template
html_url: https://github.com/Aeternalis-Ingenium/FastAPI-Backend-Template
stars: 692
owner_login: Aeternalis-Ingenium
owner_html_url: https://github.com/Aeternalis-Ingenium
- name: starlette-admin - name: starlette-admin
html_url: https://github.com/jowilf/starlette-admin html_url: https://github.com/jowilf/starlette-admin
stars: 692 stars: 713
owner_login: jowilf owner_login: jowilf
owner_html_url: https://github.com/jowilf owner_html_url: https://github.com/jowilf
- name: chatGPT-web
html_url: https://github.com/mic1on/chatGPT-web
stars: 712
owner_login: mic1on
owner_html_url: https://github.com/mic1on
- name: FastAPI-Backend-Template
html_url: https://github.com/Aeternalis-Ingenium/FastAPI-Backend-Template
stars: 709
owner_login: Aeternalis-Ingenium
owner_html_url: https://github.com/Aeternalis-Ingenium
- name: linbing
html_url: https://github.com/taomujian/linbing
stars: 698
owner_login: taomujian
owner_html_url: https://github.com/taomujian
- name: KonomiTV
html_url: https://github.com/tsukumijima/KonomiTV
stars: 687
owner_login: tsukumijima
owner_html_url: https://github.com/tsukumijima
- name: fastapi-jwt-auth - name: fastapi-jwt-auth
html_url: https://github.com/IndominusByte/fastapi-jwt-auth html_url: https://github.com/IndominusByte/fastapi-jwt-auth
stars: 674 stars: 685
owner_login: IndominusByte owner_login: IndominusByte
owner_html_url: https://github.com/IndominusByte owner_html_url: https://github.com/IndominusByte
- name: pity - name: pity
html_url: https://github.com/wuranxu/pity html_url: https://github.com/wuranxu/pity
stars: 663 stars: 667
owner_login: wuranxu owner_login: wuranxu
owner_html_url: https://github.com/wuranxu owner_html_url: https://github.com/wuranxu
- name: fastapi_login
html_url: https://github.com/MushroomMaula/fastapi_login
stars: 656
owner_login: MushroomMaula
owner_html_url: https://github.com/MushroomMaula

199
docs/en/data/translation_reviewers.yml

@ -10,9 +10,14 @@ Xewus:
url: https://github.com/Xewus url: https://github.com/Xewus
ceb10n: ceb10n:
login: ceb10n login: ceb10n
count: 110 count: 112
avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4 avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
url: https://github.com/ceb10n 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: tokusumi:
login: tokusumi login: tokusumi
count: 104 count: 104
@ -28,31 +33,26 @@ hard-coders:
count: 92 count: 92
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4 avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
url: https://github.com/hard-coders url: https://github.com/hard-coders
nazarepiedady:
login: nazarepiedady
count: 83
avatarUrl: https://avatars.githubusercontent.com/u/31008635?u=8dc25777dc9cb51fb0dbba2f137988953d330b78&v=4
url: https://github.com/nazarepiedady
AlertRED: AlertRED:
login: AlertRED login: AlertRED
count: 81 count: 81
avatarUrl: https://avatars.githubusercontent.com/u/15695000?u=f5a4944c6df443030409c88da7d7fa0b7ead985c&v=4 avatarUrl: https://avatars.githubusercontent.com/u/15695000?u=f5a4944c6df443030409c88da7d7fa0b7ead985c&v=4
url: https://github.com/AlertRED url: https://github.com/AlertRED
nazarepiedady: alv2017:
login: nazarepiedady login: alv2017
count: 81
avatarUrl: https://avatars.githubusercontent.com/u/31008635?u=8dc25777dc9cb51fb0dbba2f137988953d330b78&v=4
url: https://github.com/nazarepiedady
sodaMelon:
login: sodaMelon
count: 81 count: 81
avatarUrl: https://avatars.githubusercontent.com/u/66295123?u=be939db90f1119efee9e6110cc05066ff1f40f00&v=4 avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
url: https://github.com/sodaMelon url: https://github.com/alv2017
Alexandrhub: Alexandrhub:
login: Alexandrhub login: Alexandrhub
count: 68 count: 68
avatarUrl: https://avatars.githubusercontent.com/u/119126536?u=9fc0d48f3307817bafecc5861eb2168401a6cb04&v=4 avatarUrl: https://avatars.githubusercontent.com/u/119126536?u=9fc0d48f3307817bafecc5861eb2168401a6cb04&v=4
url: https://github.com/Alexandrhub url: https://github.com/Alexandrhub
alv2017:
login: alv2017
count: 64
avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
url: https://github.com/alv2017
waynerv: waynerv:
login: waynerv login: waynerv
count: 63 count: 63
@ -68,6 +68,11 @@ mattwang44:
count: 58 count: 58
avatarUrl: https://avatars.githubusercontent.com/u/24987826?u=58e37fb3927b9124b458945ac4c97aa0f1062d85&v=4 avatarUrl: https://avatars.githubusercontent.com/u/24987826?u=58e37fb3927b9124b458945ac4c97aa0f1062d85&v=4
url: https://github.com/mattwang44 url: https://github.com/mattwang44
tiangolo:
login: tiangolo
count: 51
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4
url: https://github.com/tiangolo
Laineyzhang55: Laineyzhang55:
login: Laineyzhang55 login: Laineyzhang55
count: 48 count: 48
@ -88,11 +93,11 @@ alperiox:
count: 42 count: 42
avatarUrl: https://avatars.githubusercontent.com/u/34214152?u=2c5acad3461d4dbc2d48371ba86cac56ae9b25cc&v=4 avatarUrl: https://avatars.githubusercontent.com/u/34214152?u=2c5acad3461d4dbc2d48371ba86cac56ae9b25cc&v=4
url: https://github.com/alperiox url: https://github.com/alperiox
tiangolo: rostik1410:
login: tiangolo login: rostik1410
count: 40 count: 41
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4 avatarUrl: https://avatars.githubusercontent.com/u/11443899?u=e26a635c2ba220467b308a326a579b8ccf4a8701&v=4
url: https://github.com/tiangolo url: https://github.com/rostik1410
Winand: Winand:
login: Winand login: Winand
count: 40 count: 40
@ -118,11 +123,31 @@ SwftAlpc:
count: 36 count: 36
avatarUrl: https://avatars.githubusercontent.com/u/52768429?u=6a3aa15277406520ad37f6236e89466ed44bc5b8&v=4 avatarUrl: https://avatars.githubusercontent.com/u/52768429?u=6a3aa15277406520ad37f6236e89466ed44bc5b8&v=4
url: https://github.com/SwftAlpc url: https://github.com/SwftAlpc
alejsdev:
login: alejsdev
count: 36
avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=356f39ff3f0211c720b06d3dbb060e98884085e3&v=4
url: https://github.com/alejsdev
timothy-jeong:
login: timothy-jeong
count: 36
avatarUrl: https://avatars.githubusercontent.com/u/53824764?u=db3d0cea2f5fab64d810113c5039a369699a2774&v=4
url: https://github.com/timothy-jeong
nilslindemann: nilslindemann:
login: nilslindemann login: nilslindemann
count: 35 count: 35
avatarUrl: https://avatars.githubusercontent.com/u/6892179?u=1dca6a22195d6cd1ab20737c0e19a4c55d639472&v=4 avatarUrl: https://avatars.githubusercontent.com/u/6892179?u=1dca6a22195d6cd1ab20737c0e19a4c55d639472&v=4
url: https://github.com/nilslindemann 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: rjNemo:
login: rjNemo login: rjNemo
count: 34 count: 34
@ -143,11 +168,6 @@ romashevchenko:
count: 32 count: 32
avatarUrl: https://avatars.githubusercontent.com/u/132477732?v=4 avatarUrl: https://avatars.githubusercontent.com/u/132477732?v=4
url: https://github.com/romashevchenko url: https://github.com/romashevchenko
alejsdev:
login: alejsdev
count: 32
avatarUrl: https://avatars.githubusercontent.com/u/90076947?u=356f39ff3f0211c720b06d3dbb060e98884085e3&v=4
url: https://github.com/alejsdev
wdh99: wdh99:
login: wdh99 login: wdh99
count: 31 count: 31
@ -208,6 +228,11 @@ junah201:
count: 26 count: 26
avatarUrl: https://avatars.githubusercontent.com/u/75025529?u=2451c256e888fa2a06bcfc0646d09b87ddb6a945&v=4 avatarUrl: https://avatars.githubusercontent.com/u/75025529?u=2451c256e888fa2a06bcfc0646d09b87ddb6a945&v=4
url: https://github.com/junah201 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: Vincy1230:
login: Vincy1230 login: Vincy1230
count: 26 count: 26
@ -248,11 +273,6 @@ wisderfin:
count: 23 count: 23
avatarUrl: https://avatars.githubusercontent.com/u/77553770?u=f3b00a26736ba664e9927a1116c6e8088295e073&v=4 avatarUrl: https://avatars.githubusercontent.com/u/77553770?u=f3b00a26736ba664e9927a1116c6e8088295e073&v=4
url: https://github.com/wisderfin url: https://github.com/wisderfin
rostik1410:
login: rostik1410
count: 22
avatarUrl: https://avatars.githubusercontent.com/u/11443899?u=e26a635c2ba220467b308a326a579b8ccf4a8701&v=4
url: https://github.com/rostik1410
AGolicyn: AGolicyn:
login: AGolicyn login: AGolicyn
count: 21 count: 21
@ -266,7 +286,7 @@ Attsun1031:
ycd: ycd:
login: ycd login: ycd
count: 20 count: 20
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=29682e4b6ac7d5293742ccf818188394b9a82972&v=4 avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=f1e7bae394a315da950912c92dc861a8eaf95d4c&v=4
url: https://github.com/ycd url: https://github.com/ycd
delhi09: delhi09:
login: delhi09 login: delhi09
@ -283,26 +303,21 @@ DevDae:
count: 20 count: 20
avatarUrl: https://avatars.githubusercontent.com/u/87962045?u=08e10fa516e844934f4b3fc7c38b33c61697e4a1&v=4 avatarUrl: https://avatars.githubusercontent.com/u/87962045?u=08e10fa516e844934f4b3fc7c38b33c61697e4a1&v=4
url: https://github.com/DevDae url: https://github.com/DevDae
svlandeg:
login: svlandeg
count: 20
avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4
url: https://github.com/svlandeg
sattosan: sattosan:
login: sattosan login: sattosan
count: 19 count: 19
avatarUrl: https://avatars.githubusercontent.com/u/20574756?u=b0d8474d2938189c6954423ae8d81d91013f80a8&v=4 avatarUrl: https://avatars.githubusercontent.com/u/20574756?u=b0d8474d2938189c6954423ae8d81d91013f80a8&v=4
url: https://github.com/sattosan url: https://github.com/sattosan
yes0ng:
login: yes0ng
count: 19
avatarUrl: https://avatars.githubusercontent.com/u/25501794?u=3aed18b0d491e0220a167a1e9e58bea3638c6707&v=4
url: https://github.com/yes0ng
ComicShrimp: ComicShrimp:
login: ComicShrimp login: ComicShrimp
count: 18 count: 18
avatarUrl: https://avatars.githubusercontent.com/u/43503750?u=d2fbf412e7730183ce91686ca48d4147e1b7dc74&v=4 avatarUrl: https://avatars.githubusercontent.com/u/43503750?u=d2fbf412e7730183ce91686ca48d4147e1b7dc74&v=4
url: https://github.com/ComicShrimp url: https://github.com/ComicShrimp
mezgoodle:
login: mezgoodle
count: 18
avatarUrl: https://avatars.githubusercontent.com/u/41520940?u=e871bc26734eb2436d98c19c3fb57a4773e13c24&v=4
url: https://github.com/mezgoodle
simatheone: simatheone:
login: simatheone login: simatheone
count: 18 count: 18
@ -473,11 +488,6 @@ kwang1215:
count: 12 count: 12
avatarUrl: https://avatars.githubusercontent.com/u/74170199?u=2a63ff6692119dde3f5e5693365b9fcd6f977b08&v=4 avatarUrl: https://avatars.githubusercontent.com/u/74170199?u=2a63ff6692119dde3f5e5693365b9fcd6f977b08&v=4
url: https://github.com/kwang1215 url: https://github.com/kwang1215
Rishat-F:
login: Rishat-F
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/66554797?v=4
url: https://github.com/Rishat-F
AdrianDeAnda: AdrianDeAnda:
login: AdrianDeAnda login: AdrianDeAnda
count: 11 count: 11
@ -498,6 +508,11 @@ glsglsgls:
count: 11 count: 11
avatarUrl: https://avatars.githubusercontent.com/u/76133879?v=4 avatarUrl: https://avatars.githubusercontent.com/u/76133879?v=4
url: https://github.com/glsglsgls url: https://github.com/glsglsgls
k94-ishi:
login: k94-ishi
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/32672580?u=bc7c5c07af0656be9fe4f1784a444af8d81ded89&v=4
url: https://github.com/k94-ishi
codespearhead: codespearhead:
login: codespearhead login: codespearhead
count: 11 count: 11
@ -586,7 +601,7 @@ waketzheng:
lucasbalieiro: lucasbalieiro:
login: lucasbalieiro login: lucasbalieiro
count: 10 count: 10
avatarUrl: https://avatars.githubusercontent.com/u/37416577?u=5a395a69384e7fa0f9840ea32ef963d3f1cd9da4&v=4 avatarUrl: https://avatars.githubusercontent.com/u/37416577?u=eabaf4aebbaa88a94a4886273edba689012cee70&v=4
url: https://github.com/lucasbalieiro url: https://github.com/lucasbalieiro
RunningIkkyu: RunningIkkyu:
login: RunningIkkyu login: RunningIkkyu
@ -648,6 +663,11 @@ Zhongheng-Cheng:
count: 9 count: 9
avatarUrl: https://avatars.githubusercontent.com/u/95612344?u=a0f7730a3cc7486827965e01a119ad610bda4b0a&v=4 avatarUrl: https://avatars.githubusercontent.com/u/95612344?u=a0f7730a3cc7486827965e01a119ad610bda4b0a&v=4
url: https://github.com/Zhongheng-Cheng url: https://github.com/Zhongheng-Cheng
Yarous:
login: Yarous
count: 9
avatarUrl: https://avatars.githubusercontent.com/u/61277193?u=5b462347458a373b2d599c6f416d2b75eddbffad&v=4
url: https://github.com/Yarous
dimaqq: dimaqq:
login: dimaqq login: dimaqq
count: 8 count: 8
@ -683,11 +703,21 @@ KimJoonSeo:
count: 8 count: 8
avatarUrl: https://avatars.githubusercontent.com/u/17760162?u=a58cdc77ae1c069a64166f7ecc4d42eecfd9a468&v=4 avatarUrl: https://avatars.githubusercontent.com/u/17760162?u=a58cdc77ae1c069a64166f7ecc4d42eecfd9a468&v=4
url: https://github.com/KimJoonSeo url: https://github.com/KimJoonSeo
MinLee0210:
login: MinLee0210
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/57653278?u=7def7c0654ad82f43b46d6dfc3b51c4d2be15011&v=4
url: https://github.com/MinLee0210
camigomezdev: camigomezdev:
login: camigomezdev login: camigomezdev
count: 8 count: 8
avatarUrl: https://avatars.githubusercontent.com/u/16061815?u=25b5ebc042fff53fa03dc107ded10e36b1b7a5b9&v=4 avatarUrl: https://avatars.githubusercontent.com/u/16061815?u=25b5ebc042fff53fa03dc107ded10e36b1b7a5b9&v=4
url: https://github.com/camigomezdev url: https://github.com/camigomezdev
maru0123-2004:
login: maru0123-2004
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/43961566?u=16ed8603a4d6a4665cb6c53a7aece6f31379b769&v=4
url: https://github.com/maru0123-2004
Serrones: Serrones:
login: Serrones login: Serrones
count: 7 count: 7
@ -843,6 +873,16 @@ bankofsardine:
count: 6 count: 6
avatarUrl: https://avatars.githubusercontent.com/u/44944207?u=0368e1b698ffab6bf29e202f9fd2dddd352429f1&v=4 avatarUrl: https://avatars.githubusercontent.com/u/44944207?u=0368e1b698ffab6bf29e202f9fd2dddd352429f1&v=4
url: https://github.com/bankofsardine url: https://github.com/bankofsardine
SofiiaTrufanova:
login: SofiiaTrufanova
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/63260929?v=4
url: https://github.com/SofiiaTrufanova
DianaTrufanova:
login: DianaTrufanova
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/119067607?v=4
url: https://github.com/DianaTrufanova
rsip22: rsip22:
login: rsip22 login: rsip22
count: 5 count: 5
@ -856,7 +896,7 @@ jessicapaz:
mohsen-mahmoodi: mohsen-mahmoodi:
login: mohsen-mahmoodi login: mohsen-mahmoodi
count: 5 count: 5
avatarUrl: https://avatars.githubusercontent.com/u/2872586?u=9274b3b13d8a992dba29b162fee48473a0fa142d&v=4 avatarUrl: https://avatars.githubusercontent.com/u/2872586?u=3a9fc1aa16a3a0ab93a1f8550de82a940592857d&v=4
url: https://github.com/mohsen-mahmoodi url: https://github.com/mohsen-mahmoodi
jeesang7: jeesang7:
login: jeesang7 login: jeesang7
@ -958,11 +998,11 @@ devluisrodrigues:
count: 5 count: 5
avatarUrl: https://avatars.githubusercontent.com/u/103431660?u=d9674a3249edc4601d2c712cdebf899918503c3a&v=4 avatarUrl: https://avatars.githubusercontent.com/u/103431660?u=d9674a3249edc4601d2c712cdebf899918503c3a&v=4
url: https://github.com/devluisrodrigues url: https://github.com/devluisrodrigues
timothy-jeong: 11kkw:
login: timothy-jeong login: 11kkw
count: 5 count: 5
avatarUrl: https://avatars.githubusercontent.com/u/53824764?u=db3d0cea2f5fab64d810113c5039a369699a2774&v=4 avatarUrl: https://avatars.githubusercontent.com/u/21125286?v=4
url: https://github.com/timothy-jeong url: https://github.com/11kkw
lpdswing: lpdswing:
login: lpdswing login: lpdswing
count: 4 count: 4
@ -976,7 +1016,7 @@ SepehrRasouli:
Zxilly: Zxilly:
login: Zxilly login: Zxilly
count: 4 count: 4
avatarUrl: https://avatars.githubusercontent.com/u/31370133?u=122e23d6e974614736be606e4ea816f45e7745f8&v=4 avatarUrl: https://avatars.githubusercontent.com/u/31370133?u=c5359b8d9d80a7cdc23d5295d179ed90174996c8&v=4
url: https://github.com/Zxilly url: https://github.com/Zxilly
eavv: eavv:
login: eavv login: eavv
@ -1016,7 +1056,7 @@ personage-hub:
aminalaee: aminalaee:
login: aminalaee login: aminalaee
count: 4 count: 4
avatarUrl: https://avatars.githubusercontent.com/u/19784933?u=2f45a312b73e7fb29f3b6f8676e5be6f7220da25&v=4 avatarUrl: https://avatars.githubusercontent.com/u/19784933?v=4
url: https://github.com/aminalaee url: https://github.com/aminalaee
erfan-rfmhr: erfan-rfmhr:
login: erfan-rfmhr login: erfan-rfmhr
@ -1058,11 +1098,11 @@ matiasbertani:
count: 4 count: 4
avatarUrl: https://avatars.githubusercontent.com/u/65260383?u=d5edd86a6e2ab4fb1aab7751931fe045a963afd7&v=4 avatarUrl: https://avatars.githubusercontent.com/u/65260383?u=d5edd86a6e2ab4fb1aab7751931fe045a963afd7&v=4
url: https://github.com/matiasbertani url: https://github.com/matiasbertani
k94-ishi: thiennc254:
login: k94-ishi login: thiennc254
count: 4 count: 4
avatarUrl: https://avatars.githubusercontent.com/u/32672580?u=bc7c5c07af0656be9fe4f1784a444af8d81ded89&v=4 avatarUrl: https://avatars.githubusercontent.com/u/97406628?u=1b2860679694b9a552764d0fa81dbd7a016322ec&v=4
url: https://github.com/k94-ishi url: https://github.com/thiennc254
javillegasna: javillegasna:
login: javillegasna login: javillegasna
count: 4 count: 4
@ -1078,11 +1118,16 @@ ilhamfadillah:
count: 4 count: 4
avatarUrl: https://avatars.githubusercontent.com/u/20577838?u=c56192cf99b55affcaad408b240259c62e633450&v=4 avatarUrl: https://avatars.githubusercontent.com/u/20577838?u=c56192cf99b55affcaad408b240259c62e633450&v=4
url: https://github.com/ilhamfadillah url: https://github.com/ilhamfadillah
Yarous: gerry-sabar:
login: Yarous login: gerry-sabar
count: 4 count: 4
avatarUrl: https://avatars.githubusercontent.com/u/61277193?u=5b462347458a373b2d599c6f416d2b75eddbffad&v=4 avatarUrl: https://avatars.githubusercontent.com/u/1120123?v=4
url: https://github.com/Yarous url: https://github.com/gerry-sabar
valentinDruzhinin:
login: valentinDruzhinin
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/12831905?u=aae1ebc675c91e8fa582df4fcc4fc4128106344d&v=4
url: https://github.com/valentinDruzhinin
tyronedamasceno: tyronedamasceno:
login: tyronedamasceno login: tyronedamasceno
count: 3 count: 3
@ -1308,11 +1353,16 @@ RyaWcksn:
count: 3 count: 3
avatarUrl: https://avatars.githubusercontent.com/u/42831964?u=0cb4265faf3e3425a89e59b6fddd3eb2de180af0&v=4 avatarUrl: https://avatars.githubusercontent.com/u/42831964?u=0cb4265faf3e3425a89e59b6fddd3eb2de180af0&v=4
url: https://github.com/RyaWcksn url: https://github.com/RyaWcksn
gerry-sabar: Zerohertz:
login: gerry-sabar login: Zerohertz
count: 3 count: 3
avatarUrl: https://avatars.githubusercontent.com/u/1120123?v=4 avatarUrl: https://avatars.githubusercontent.com/u/42334717?u=c6acda352c866b1747921e0ff8782b58571d849e&v=4
url: https://github.com/gerry-sabar url: https://github.com/Zerohertz
tienduong-21:
login: tienduong-21
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/80129618?v=4
url: https://github.com/tienduong-21
blaisep: blaisep:
login: blaisep login: blaisep
count: 2 count: 2
@ -1471,7 +1521,7 @@ felipebpl:
iudeen: iudeen:
login: iudeen login: iudeen
count: 2 count: 2
avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4 avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=f09cdd745e5bf16138f29b42732dd57c7f02bee1&v=4
url: https://github.com/iudeen url: https://github.com/iudeen
dwisulfahnur: dwisulfahnur:
login: dwisulfahnur login: dwisulfahnur
@ -1623,6 +1673,16 @@ UN-9BOT:
count: 2 count: 2
avatarUrl: https://avatars.githubusercontent.com/u/111110804?u=39e158937ed795972c2d0400fc521c50e9bfb9e7&v=4 avatarUrl: https://avatars.githubusercontent.com/u/111110804?u=39e158937ed795972c2d0400fc521c50e9bfb9e7&v=4
url: https://github.com/UN-9BOT url: https://github.com/UN-9BOT
flasonme:
login: flasonme
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/30571019?v=4
url: https://github.com/flasonme
ptt3199:
login: ptt3199
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/51350651?u=ccf51f8820787e17983954f26b06acf226cba293&v=4
url: https://github.com/ptt3199
gustavoprezoto: gustavoprezoto:
login: gustavoprezoto login: gustavoprezoto
count: 2 count: 2
@ -1668,3 +1728,8 @@ kiharito:
count: 2 count: 2
avatarUrl: https://avatars.githubusercontent.com/u/38311245?v=4 avatarUrl: https://avatars.githubusercontent.com/u/38311245?v=4
url: https://github.com/kiharito url: https://github.com/kiharito
J-Fuji:
login: J-Fuji
count: 2
avatarUrl: https://avatars.githubusercontent.com/u/101452903?v=4
url: https://github.com/J-Fuji

56
docs/en/data/translators.yml

@ -10,7 +10,7 @@ jaystone776:
url: https://github.com/jaystone776 url: https://github.com/jaystone776
ceb10n: ceb10n:
login: ceb10n login: ceb10n
count: 26 count: 27
avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4 avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4
url: https://github.com/ceb10n url: https://github.com/ceb10n
tokusumi: tokusumi:
@ -43,21 +43,26 @@ hard-coders:
count: 15 count: 15
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4 avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
url: https://github.com/hard-coders url: https://github.com/hard-coders
Joao-Pedro-P-Holanda:
login: Joao-Pedro-P-Holanda
count: 14
avatarUrl: https://avatars.githubusercontent.com/u/110267046?u=331bd016326dac4cf3df4848f6db2dbbf8b5f978&v=4
url: https://github.com/Joao-Pedro-P-Holanda
codingjenny: codingjenny:
login: codingjenny login: codingjenny
count: 14 count: 14
avatarUrl: https://avatars.githubusercontent.com/u/103817302?u=3a042740dc0ff58615da0d8679230966fd7693e8&v=4 avatarUrl: https://avatars.githubusercontent.com/u/103817302?u=3a042740dc0ff58615da0d8679230966fd7693e8&v=4
url: https://github.com/codingjenny 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: Xewus:
login: Xewus login: Xewus
count: 13 count: 13
avatarUrl: https://avatars.githubusercontent.com/u/85196001?u=f8e2dc7e5104f109cef944af79050ea8d1b8f914&v=4 avatarUrl: https://avatars.githubusercontent.com/u/85196001?u=f8e2dc7e5104f109cef944af79050ea8d1b8f914&v=4
url: https://github.com/Xewus url: https://github.com/Xewus
Joao-Pedro-P-Holanda:
login: Joao-Pedro-P-Holanda
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/110267046?u=331bd016326dac4cf3df4848f6db2dbbf8b5f978&v=4
url: https://github.com/Joao-Pedro-P-Holanda
Smlep: Smlep:
login: Smlep login: Smlep
count: 11 count: 11
@ -106,13 +111,18 @@ batlopes:
lucasbalieiro: lucasbalieiro:
login: lucasbalieiro login: lucasbalieiro
count: 6 count: 6
avatarUrl: https://avatars.githubusercontent.com/u/37416577?u=5a395a69384e7fa0f9840ea32ef963d3f1cd9da4&v=4 avatarUrl: https://avatars.githubusercontent.com/u/37416577?u=eabaf4aebbaa88a94a4886273edba689012cee70&v=4
url: https://github.com/lucasbalieiro url: https://github.com/lucasbalieiro
Alexandrhub: Alexandrhub:
login: Alexandrhub login: Alexandrhub
count: 6 count: 6
avatarUrl: https://avatars.githubusercontent.com/u/119126536?u=9fc0d48f3307817bafecc5861eb2168401a6cb04&v=4 avatarUrl: https://avatars.githubusercontent.com/u/119126536?u=9fc0d48f3307817bafecc5861eb2168401a6cb04&v=4
url: https://github.com/Alexandrhub 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: Serrones:
login: Serrones login: Serrones
count: 5 count: 5
@ -143,6 +153,11 @@ rostik1410:
count: 5 count: 5
avatarUrl: https://avatars.githubusercontent.com/u/11443899?u=e26a635c2ba220467b308a326a579b8ccf4a8701&v=4 avatarUrl: https://avatars.githubusercontent.com/u/11443899?u=e26a635c2ba220467b308a326a579b8ccf4a8701&v=4
url: https://github.com/rostik1410 url: https://github.com/rostik1410
alv2017:
login: alv2017
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
url: https://github.com/alv2017
komtaki: komtaki:
login: komtaki login: komtaki
count: 4 count: 4
@ -188,11 +203,6 @@ kwang1215:
count: 4 count: 4
avatarUrl: https://avatars.githubusercontent.com/u/74170199?u=2a63ff6692119dde3f5e5693365b9fcd6f977b08&v=4 avatarUrl: https://avatars.githubusercontent.com/u/74170199?u=2a63ff6692119dde3f5e5693365b9fcd6f977b08&v=4
url: https://github.com/kwang1215 url: https://github.com/kwang1215
alv2017:
login: alv2017
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4
url: https://github.com/alv2017
jfunez: jfunez:
login: jfunez login: jfunez
count: 3 count: 3
@ -201,7 +211,7 @@ jfunez:
ycd: ycd:
login: ycd login: ycd
count: 3 count: 3
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=29682e4b6ac7d5293742ccf818188394b9a82972&v=4 avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=f1e7bae394a315da950912c92dc861a8eaf95d4c&v=4
url: https://github.com/ycd url: https://github.com/ycd
mariacamilagl: mariacamilagl:
login: mariacamilagl login: mariacamilagl
@ -323,6 +333,16 @@ gerry-sabar:
count: 3 count: 3
avatarUrl: https://avatars.githubusercontent.com/u/1120123?v=4 avatarUrl: https://avatars.githubusercontent.com/u/1120123?v=4
url: https://github.com/gerry-sabar url: https://github.com/gerry-sabar
k94-ishi:
login: k94-ishi
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/32672580?u=bc7c5c07af0656be9fe4f1784a444af8d81ded89&v=4
url: https://github.com/k94-ishi
Rishat-F:
login: Rishat-F
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/66554797?v=4
url: https://github.com/Rishat-F
izaguerreiro: izaguerreiro:
login: izaguerreiro login: izaguerreiro
count: 2 count: 2
@ -451,7 +471,7 @@ choi-haram:
imtiaz101325: imtiaz101325:
login: imtiaz101325 login: imtiaz101325
count: 2 count: 2
avatarUrl: https://avatars.githubusercontent.com/u/54007087?u=7a210ee38a0a30b7536226419b3b799620ad57d9&v=4 avatarUrl: https://avatars.githubusercontent.com/u/54007087?u=194d972b501b9ea9d2ddeaed757c492936e0121a&v=4
url: https://github.com/imtiaz101325 url: https://github.com/imtiaz101325
waketzheng: waketzheng:
login: waketzheng login: waketzheng
@ -488,8 +508,8 @@ timothy-jeong:
count: 2 count: 2
avatarUrl: https://avatars.githubusercontent.com/u/53824764?u=db3d0cea2f5fab64d810113c5039a369699a2774&v=4 avatarUrl: https://avatars.githubusercontent.com/u/53824764?u=db3d0cea2f5fab64d810113c5039a369699a2774&v=4
url: https://github.com/timothy-jeong url: https://github.com/timothy-jeong
Rishat-F: 11kkw:
login: Rishat-F login: 11kkw
count: 2 count: 2
avatarUrl: https://avatars.githubusercontent.com/u/66554797?v=4 avatarUrl: https://avatars.githubusercontent.com/u/21125286?v=4
url: https://github.com/Rishat-F url: https://github.com/11kkw

15
docs/en/docs/advanced/index.md

@ -19,18 +19,3 @@ And it's possible that for your use case, the solution is in one of them.
You could still use most of the features in **FastAPI** with the knowledge from the main [Tutorial - User Guide](../tutorial/index.md){.internal-link target=_blank}. You could still use most of the features in **FastAPI** with the knowledge from the main [Tutorial - User Guide](../tutorial/index.md){.internal-link target=_blank}.
And the next sections assume you already read it, and assume that you know those main ideas. And the next sections assume you already read it, and assume that you know those main ideas.
## External Courses
Although the [Tutorial - User Guide](../tutorial/index.md){.internal-link target=_blank} and this **Advanced User Guide** are written as a guided tutorial (like a book) and should be enough for you to **learn FastAPI**, you might want to complement it with additional courses.
Or it might be the case that you just prefer to take other courses because they adapt better to your learning style.
Some course providers ✨ [**sponsor FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, this ensures the continued and healthy **development** of FastAPI and its **ecosystem**.
And it shows their true commitment to FastAPI and its **community** (you), as they not only want to provide you a **good learning experience** but also want to make sure you have a **good and healthy framework**, FastAPI. 🙇
You might want to try their courses:
* <a href="https://training.talkpython.fm/fastapi-courses" class="external-link" target="_blank">Talk Python Training</a>
* <a href="https://testdriven.io/courses/tdd-fastapi/" class="external-link" target="_blank">Test-Driven Development</a>

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

@ -9,8 +9,33 @@ hide:
### Translations ### Translations
* 🌐 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 sqlmodel from 0.0.22 to 0.0.23. PR [#13437](https://github.com/fastapi/fastapi/pull/13437) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump black from 24.10.0 to 25.1.0. PR [#13436](https://github.com/fastapi/fastapi/pull/13436) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump ruff to 0.9.4. PR [#13299](https://github.com/fastapi/fastapi/pull/13299) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 🔧 Update sponsors: pause TestDriven. PR [#13446](https://github.com/fastapi/fastapi/pull/13446) by [@tiangolo](https://github.com/tiangolo).
## 0.115.11
### Fixes
* 🐛 Add docs examples and tests (support) for `Annotated` custom validations, like `AfterValidator`, revert [#13440](https://github.com/fastapi/fastapi/pull/13440). PR [#13442](https://github.com/fastapi/fastapi/pull/13442) by [@tiangolo](https://github.com/tiangolo).
* New docs: [Query Parameters and String Validations - Custom Validation](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#custom-validation).
### Translations
* 🌐 Add Russian translation for `docs/ru/docs/tutorial/middleware.md`. PR [#13412](https://github.com/fastapi/fastapi/pull/13412) by [@alv2017](https://github.com/alv2017). * 🌐 Add Russian translation for `docs/ru/docs/tutorial/middleware.md`. PR [#13412](https://github.com/fastapi/fastapi/pull/13412) by [@alv2017](https://github.com/alv2017).
### Internal
* 👥 Update FastAPI GitHub topic repositories. PR [#13439](https://github.com/fastapi/fastapi/pull/13439) by [@tiangolo](https://github.com/tiangolo).
* 👥 Update FastAPI People - Contributors and Translators. PR [#13432](https://github.com/fastapi/fastapi/pull/13432) by [@tiangolo](https://github.com/tiangolo).
* 👥 Update FastAPI People - Sponsors. PR [#13433](https://github.com/fastapi/fastapi/pull/13433) by [@tiangolo](https://github.com/tiangolo).
## 0.115.10 ## 0.115.10
### Fixes ### Fixes

64
docs/en/docs/tutorial/query-params-str-validations.md

@ -406,6 +406,68 @@ To exclude a query parameter from the generated OpenAPI schema (and thus, from t
{* ../../docs_src/query_params_str_validations/tutorial014_an_py310.py hl[10] *} {* ../../docs_src/query_params_str_validations/tutorial014_an_py310.py hl[10] *}
## Custom Validation
There could be cases where you need to do some **custom validation** that can't be done with the parameters shown above.
In those cases, you can use a **custom validator function** that is applied after the normal validation (e.g. after validating that the value is a `str`).
You can achieve that using <a href="https://docs.pydantic.dev/latest/concepts/validators/#field-after-validator" class="external-link" target="_blank">Pydantic's `AfterValidator`</a> inside of `Annotated`.
/// tip
Pydantic also has <a href="https://docs.pydantic.dev/latest/concepts/validators/#field-before-validator" class="external-link" target="_blank">`BeforeValidator`</a> and others. 🤓
///
For example, this custom validator checks that the item ID starts with `isbn-` for an <abbr title="ISBN means International Standard Book Number">ISBN</abbr> book number or with `imdb-` for an <abbr title="IMDB (Internet Movie Database) is a website with information about movies">IMDB</abbr> movie URL ID:
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py hl[5,16:19,24] *}
/// info
This is available with Pydantic version 2 or above. 😎
///
/// tip
If you need to do any type of validation that requires communicating with any **external component**, like a database or another API, you should instead use **FastAPI Dependencies**, you will learn about them later.
These custom validators are for things that can be checked with **only** the **same data** provided in the request.
///
### Understand that Code
The important point is just using **`AfterValidator` with a function inside `Annotated`**. Feel free to skip this part. 🤸
---
But if you're curious about this specific code example and you're still entertained, here are some extra details.
#### String with `value.startswith()`
Did you notice? a string using `value.startswith()` can take a tuple, and it will check each value in the tuple:
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[16:19] hl[17] *}
#### A Random Item
With `data.items()` we get an <abbr title="Something we can iterate on with a for loop, like a list, set, etc.">iterable object</abbr> with tuples containing the key and value for each dictionary item.
We convert this iterable object into a proper `list` with `list(data.items())`.
Then with `random.choice()` we can get a **random value** from the list, so, we get a tuple with `(id, name)`. It will be something like `("imdb-tt0371724", "The Hitchhiker's Guide to the Galaxy")`.
Then we **assign those two values** of the tuple to the variables `id` and `name`.
So, if the user didn't provide an item ID, they will still receive a random suggestion.
...we do all this in a **single simple line**. 🤯 Don't you love Python? 🐍
{* ../../docs_src/query_params_str_validations/tutorial015_an_py310.py ln[22:30] hl[29] *}
## Recap ## Recap
You can declare additional validations and metadata for your parameters. You can declare additional validations and metadata for your parameters.
@ -423,6 +485,8 @@ Validations specific for strings:
* `max_length` * `max_length`
* `pattern` * `pattern`
Custom validations using `AfterValidator`.
In these examples you saw how to declare validations for `str` values. In these examples you saw how to declare validations for `str` values.
See the next chapters to learn how to declare validations for other types, like numbers. See the next chapters to learn how to declare validations for other types, like numbers.

273
docs/ko/docs/tutorial/security/oauth2-jwt.md

@ -0,0 +1,273 @@
# 패스워드 해싱을 이용한 OAuth2, JWT 토큰을 사용하는 Bearer 인증
모든 보안 흐름을 구성했으므로, 이제 <abbr title="JSON Web Tokens">JWT</abbr> 토큰과 패스워드 해싱을 사용해 애플리케이션을 안전하게 만들 것입니다.
이 코드는 실제로 애플리케이션에서 패스워드를 해싱하여 DB에 저장하는 등의 작업에 활용할 수 있습니다.
이전 장에 이어서 시작해 봅시다.
## JWT
JWT 는 "JSON Web Tokens" 을 의미합니다.
JSON 객체를 공백이 없는 긴 문자열로 인코딩하는 표준이며, 다음과 같은 형태입니다:
```
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
```
JWT는 암호화되지 않아 누구든지 토큰에서 정보를 복원할 수 있습니다.
하지만 JWT는 서명되어 있습니다. 그래서 자신이 발급한 토큰을 받았을 때, 실제로 자신이 발급한게 맞는지 검증할 수 있습니다.
만료 기간이 일주일인 토큰을 발행했다고 가정해 봅시다. 다음 날 사용자가 토큰을 가져왔을 때, 그 사용자가 시스템에 여전히 로그인되어 있다는 것을 알 수 있습니다.
일주일 뒤에는 토큰이 만료될 것이고, 사용자는 인가되지 않아 새 토큰을 받기 위해 다시 로그인해야 할 것입니다. 만약 사용자(또는 제3자)가 토큰을 수정하거나 만료일을 변경하면, 서명이 일치하지 않기 때문에 알아챌 수 있을 것입니다.
만약 JWT 토큰을 다뤄보고, 작동 방식도 알아보고 싶다면 <a href="https://jwt.io/" class="external-link" target="_blank">https://jwt.io</a> 을 확인하십시오.
## `PyJWT` 설치
파이썬으로 JWT 토큰을 생성하고 검증하려면 `PyJWT` 를 설치해야 합니다.
[가상환경](../../virtual-environments.md){.internal-link target=_blank} 을 만들고 활성화한 다음 `pyjwt` 를 설치하십시오:
<div class="termy">
```console
$ pip install pyjwt
---> 100%
```
</div>
/// info | 참고
RSA나 ECDSA 같은 전자 서명 알고리즘을 사용하려면, `pyjwt[crypto]`라는 암호화 라이브러리 의존성을 설치해야 합니다.
더 자세한 내용은 <a href="https://pyjwt.readthedocs.io/en/latest/installation.html" class="external-link" target="_blank">PyJWT 설치</a> 에서 확인할 수 있습니다.
///
## 패스워드 해싱
"해싱(Hashing)"은 어떤 내용(여기서는 패스워드)을 해석할 수 없는 일련의 바이트 집합(단순 문자열)으로 변환하는 것을 의미합니다.
동일한 내용(똑같은 패스워드)을 해싱하면 동일한 문자열을 얻습니다.
하지만 그 문자열을 다시 패스워드로 되돌릴 수는 없습니다.
### 패스워드를 해싱하는 이유
데이터베이스를 탈취당하더라도, 침입자는 사용자의 평문 패스워드 대신 해시 값만 얻을 수 있습니다.
따라서 침입자는 훔친 사용자 패스워드를 다른 시스템에서 활용할 수 없습니다. (대다수 사용자가 여러 시스템에서 동일한 패스워드를 사용하기 때문에 평문 패스워드가 유출되면 위험합니다.)
## `passlib` 설치
PassLib는 패스워드 해시를 다루는 훌륭한 파이썬 패키지입니다.
많은 안전한 해시 알고리즘과 도구들을 지원합니다.
추천하는 알고리즘은 "Bcrypt"입니다.
[가상환경](../../virtual-environments.md){.internal-link target=_blank} 을 만들고 활성화한 다음 PassLib와 Bcrypt를 설치하십시오:
<div class="termy">
```console
$ pip install "passlib[bcrypt]"
---> 100%
```
</div>
/// tip | 팁
`passlib`를 사용하여, **Django**, **Flask** 의 보안 플러그인이나 다른 도구로 생성한 패스워드를 읽을 수 있도록 설정할 수도 있습니다.
예를 들자면, FastAPI 애플리케이션과 Django 애플리케이션이 같은 데이터베이스에서 데이터를 공유할 수 있습니다. 또는 같은 데이터베이스를 사용하여 Django 애플리케이션을 점진적으로 마이그레이션 할 수도 있습니다.
그리고 사용자는 FastAPI 애플리케이션과 Django 애플리케이션에 동시에 로그인할 수 있습니다.
///
## 패스워드의 해시와 검증
필요한 도구를 `passlib`에서 임포트합니다.
PassLib "컨텍스트(context)"를 생성합니다. 이것은 패스워드를 해싱하고 검증하는데 사용합니다.
/// tip | 팁
PassLib 컨텍스트는 다양한 해싱 알고리즘을 사용할 수 있는 기능을 제공하며, 더 이상 사용이 권장되지 않는 오래된 해싱 알고리즘을 검증하는 기능도 포함되어 있습니다.
예를 들어, 다른 시스템(Django 같은)에서 생성한 패스워드를 읽고 검증할 수 있으며, 새로운 패스워드를 Bcrypt 같은 다른 알고리즘으로 해싱할 수도 있습니다.
그리고 동시에 그런 모든 알고리즘과 호환성을 유지합니다.
///
사용자로부터 받은 패스워드를 해싱하는 유틸리티 함수를 생성합니다.
그리고 받은 패스워드가 저장된 해시와 일치하는지 검증하는 또 다른 유틸리티 함수도 생성합니다.
그리고 사용자를 인증하고 반환하는 또 다른 함수도 생성합니다.
{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,56:57,60:61,70:76] *}
/// note
새로운 (가짜) 데이터베이스 `fake_users_db`를 확인하면, 해시 처리된 패스워드가 어떻게 생겼는지 볼 수 있습니다: `"$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW"`.
///
## JWT 토큰 처리
설치된 모듈을 임포트 합니다.
JWT 토큰 서명에 사용될 임의의 비밀키를 생성합니다.
안전한 임의의 비밀키를 생성하려면 다음 명령어를 사용하십시오:
<div class="termy">
```console
$ openssl rand -hex 32
09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7
```
</div>
그리고 생성한 비밀키를 복사해 변수 `SECRET_KEY`에 대입합니다. (이 예제의 변수 값을 그대로 사용하지 마십시오.)
JWT 토큰을 서명하는 데 사용될 알고리즘을 위한 변수 `ALGORITHM` 을 생성하고 `"HS256"` 으로 설정합니다.
토큰 만료 기간을 위한 변수를 생성합니다.
응답을 위한 토큰 엔드포인트에 사용될 Pydantic 모델을 정의합니다.
새 액세스 토큰을 생성하기 위한 유틸리티 함수를 생성합니다.
{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,79:87] *}
## 의존성 수정
`get_current_user` 함수를 이전과 동일한 토큰을 받도록 수정하되, 이번에는 JWT 토큰을 사용하도록 합니다.
받은 토큰을 디코딩하여 검증한 후 현재 사용자를 반환합니다.
토큰이 유효하지 않다면 HTTP 오류를 반환합니다.
{* ../../docs_src/security/tutorial004_an_py310.py hl[90:107] *}
## `/token` 경로 작업 수정
토큰의 만료 시각을 설정하기 위해 `timedelta` 를 생성합니다.
실제 JWT 액세스 토큰을 생성하여 반환합니다.
{* ../../docs_src/security/tutorial004_an_py310.py hl[118:133] *}
### JWT "주체(subject)" `sub`에 대한 기술 세부 사항
JWT 명세에 따르면 토큰의 주체를 포함하는 `sub`라는 키가 있습니다.
사용 여부는 선택사항이지만, 사용자의 식별 정보를 저장할 수 있으므로 여기서는 이를 사용합니다.
JWT는 사용자를 식별하고 사용자가 API를 직접 사용할 수 있도록 허용하는 것 외에도 다른 용도로 사용될 수도 있습니다.
예를 들어 "자동차"나 "블로그 게시물"을 식별하는 데 사용할 수 있습니다.
그리고 "자동차를 운전하다"나 "블로그 게시물을 수정하다"처럼 해당 엔터티에 대한 권한을 추가할 수 있습니다.
그 후 이 JWT 토큰을 사용자(또는 봇)에게 제공하면, 그들은 계정을 따로 만들 필요 없이 API가 생성한 JWT 토큰만으로 작업(자동차 운전 또는 블로그 게시물 편집)을 수행할 수 있습니다.
이러한 개념을 활용하면 JWT는 훨씬 더 복잡한 시나리오에도 사용할 수 있습니다.
이 경우 여러 엔터티가 동일한 ID를 가질 수 있습니다. 예를 들어 foo라는 ID를 가진 사용자, 자동차, 블로그 게시물이 있을 수 있습니다.
그래서 ID 충돌을 방지하기 위해, 사용자의 JWT 토큰을 생성할 때 접두사로 `sub` 키를 추가할 수 있습니다. 예를 들어 `username:` 을 붙이는 방식입니다. 이 예제에서는 `sub` 값이 `username:johndoe`이 될 수 있습니다.
가장 중요한 점은 `sub` 키는 전체 애플리케이션에서 고유한 식별자가 되어야 하며 문자열이어야 한다는 점입니다.
## 확인해봅시다
서버를 실행하고 문서로 이동하십시오: <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
다음과 같은 사용자 인터페이스를 볼 수 있습니다:
<img src="/img/tutorial/security/image07.png">
이전과 같은 방법으로 애플리케이션에 인증하십시오.
다음 인증 정보를 사용하십시오:
Username: `johndoe`
Password: `secret`
/// check
코드 어디에도 평문 패스워드 "`secret`" 이 없다는 점에 유의하십시오. 해시된 버전만 있습니다.
///
<img src="/img/tutorial/security/image08.png">
`/users/me/` 를 호출하면 다음과 같은 응답을 얻을 수 있습니다:
```JSON
{
"username": "johndoe",
"email": "[email protected]",
"full_name": "John Doe",
"disabled": false
}
```
<img src="/img/tutorial/security/image09.png">
개발자 도구를 열어보면 전송된 데이터에 토큰만 포함된 것을 확인할 수 있습니다. 패스워드는 사용자를 인증하고 액세스 토큰을 받기 위한 첫 번째 요청에만 전송되며, 이후에는 전송되지 않습니다:
<img src="/img/tutorial/security/image10.png">
/// note
`Bearer `로 시작하는 `Authorization` 헤더에 주목하십시오.
///
## `scopes` 의 고급 사용법
OAuth2는 "스코프(scopes)" 라는 개념을 갖고 있습니다.
이를 사용하여 JWT 토큰에 특정 권한 집합을 추가할 수 있습니다.
그 후 이 토큰을 사용자에게 직접 제공하거나 제3자에게 제공하여, 특정 제한사항 하에있는 API와 통신하도록 할 수 있습니다.
**FastAPI** 에서의 사용 방법과 통합 방식은 **심화 사용자 안내서** 에서 자세히 배울 수 있습니다.
## 요약
지금까지 살펴본 내용을 바탕으로, OAuth2와 JWT 같은 표준을 사용하여 안전한 **FastAPI** 애플리케이션을 만들 수 있습니다.
거의 모든 프레임워크에서 보안 처리는 상당히 복잡한 주제입니다.
이를 단순화하는 많은 패키지는 데이터 모델, 데이터베이스, 사용 가능한 기능들에 대해 여러 제약이 있습니다. 그리고 지나치게 단순화하는 일부 패키지들은 심각한 보안 결함을 가질 수도 있습니다.
---
**FastAPI** 는 어떤 데이터베이스, 데이터 모델, 도구도 강요하지 않습니다.
프로젝트에 가장 적합한 것을 선택할 수 있는 유연성을 제공합니다.
그리고 `passlib``PyJWT` 처럼 잘 관리되고 널리 사용되는 패키지들을 바로 사용할 수 있습니다. **FastAPI** 는 외부 패키지 통합을 위해 복잡한 메커니즘이 필요하지 않기 때문입니다.
그러나 유연성, 견고성, 보안성을 해치지 않으면서 과정을 단순화할 수 있는 도구들을 제공합니다.
그리고 OAuth2와 같은 표준 프로토콜을 비교적 간단한 방법으로 구현하고 사용할 수 있습니다.
더 세분화된 권한 체계를 위해 OAuth2의 "스코프"를 사용하는 방법은 **심화 사용자 안내서**에서 더 자세히 배울 수 있습니다. OAuth2의 스코프는 제3자 애플리케이션이 사용자를 대신해 그들의 API와 상호작용하도록 권한을 부여하기 위해, Facebook, Google, GitHub, Microsoft, Twitter 등의 많은 대형 인증 제공업체들이 사용하는 메커니즘입니다.

17
docs/vi/docs/deployment/cloud.md

@ -0,0 +1,17 @@
# Triển khai FastAPI trên các Dịch vụ Cloud
Bạn có thể sử dụng **bất kỳ nhà cung cấp dịch vụ cloud** nào để triển khai ứng dụng FastAPI của mình.
Trong hầu hết các trường hợp, các nhà cung cấp dịch vụ cloud lớn đều có hướng dẫn triển khai FastAPI với họ.
## Nhà cung cấp dịch vụ Cloud - Nhà tài trợ
Một vài nhà cung cấp dịch vụ cloud ✨ [**tài trợ cho FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, điều này giúp đảm bảo sự phát triển liên tục và khỏe mạnh của FastAPI và hệ sinh thái của nó.
Thêm nữa, điều này cũng thể hiện cam kết thực sự của họ đối với FastAPI và **cộng đồng người dùng** (bạn), vì họ không chỉ muốn cung cấp cho bạn một **dịch vụ tốt** mà còn muốn đảm bảo rằng bạn có một **framework tốt và bền vững**, đó chính là FastAPI. 🙇
Bạn có thể thử các dịch vụ của họ và làm theo hướng dẫn của họ:
* <a href="https://docs.platform.sh/languages/python.html?utm_source=fastapi-signup&utm_medium=banner&utm_campaign=FastAPI-signup-June-2023" class="external-link" target="_blank">Platform.sh</a>
* <a href="https://docs.porter.run/language-specific-guides/fastapi" class="external-link" target="_blank">Porter</a>
* <a href="https://www.withcoherence.com/?utm_medium=advertising&utm_source=fastapi&utm_campaign=website" class="external-link" target="_blank">Coherence</a>
* <a href="https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi" class="external-link" target="_blank">Render</a>

31
docs_src/query_params_str_validations/tutorial015_an.py

@ -0,0 +1,31 @@
import random
from typing import Union
from fastapi import FastAPI
from pydantic import AfterValidator
from typing_extensions import Annotated
app = FastAPI()
data = {
"isbn-9781529046137": "The Hitchhiker's Guide to the Galaxy",
"imdb-tt0371724": "The Hitchhiker's Guide to the Galaxy",
"isbn-9781439512982": "Isaac Asimov: The Complete Stories, Vol. 2",
}
def check_valid_id(id: str):
if not id.startswith(("isbn-", "imdb-")):
raise ValueError('Invalid ID format, it must start with "isbn-" or "imdb-"')
return id
@app.get("/items/")
async def read_items(
id: Annotated[Union[str, None], AfterValidator(check_valid_id)] = None,
):
if id:
item = data.get(id)
else:
id, item = random.choice(list(data.items()))
return {"id": id, "name": item}

30
docs_src/query_params_str_validations/tutorial015_an_py310.py

@ -0,0 +1,30 @@
import random
from typing import Annotated
from fastapi import FastAPI
from pydantic import AfterValidator
app = FastAPI()
data = {
"isbn-9781529046137": "The Hitchhiker's Guide to the Galaxy",
"imdb-tt0371724": "The Hitchhiker's Guide to the Galaxy",
"isbn-9781439512982": "Isaac Asimov: The Complete Stories, Vol. 2",
}
def check_valid_id(id: str):
if not id.startswith(("isbn-", "imdb-")):
raise ValueError('Invalid ID format, it must start with "isbn-" or "imdb-"')
return id
@app.get("/items/")
async def read_items(
id: Annotated[str | None, AfterValidator(check_valid_id)] = None,
):
if id:
item = data.get(id)
else:
id, item = random.choice(list(data.items()))
return {"id": id, "name": item}

30
docs_src/query_params_str_validations/tutorial015_an_py39.py

@ -0,0 +1,30 @@
import random
from typing import Annotated, Union
from fastapi import FastAPI
from pydantic import AfterValidator
app = FastAPI()
data = {
"isbn-9781529046137": "The Hitchhiker's Guide to the Galaxy",
"imdb-tt0371724": "The Hitchhiker's Guide to the Galaxy",
"isbn-9781439512982": "Isaac Asimov: The Complete Stories, Vol. 2",
}
def check_valid_id(id: str):
if not id.startswith(("isbn-", "imdb-")):
raise ValueError('Invalid ID format, it must start with "isbn-" or "imdb-"')
return id
@app.get("/items/")
async def read_items(
id: Annotated[Union[str, None], AfterValidator(check_valid_id)] = None,
):
if id:
item = data.get(id)
else:
id, item = random.choice(list(data.items()))
return {"id": id, "name": item}

2
fastapi/__init__.py

@ -1,6 +1,6 @@
"""FastAPI framework, high performance, easy to learn, fast to code, ready for production""" """FastAPI framework, high performance, easy to learn, fast to code, ready for production"""
__version__ = "0.115.10" __version__ = "0.115.11"
from starlette import status as status from starlette import status as status

50
fastapi/dependencies/utils.py

@ -133,9 +133,9 @@ def get_param_sub_dependant(
def get_parameterless_sub_dependant(*, depends: params.Depends, path: str) -> Dependant: def get_parameterless_sub_dependant(*, depends: params.Depends, path: str) -> Dependant:
assert callable( assert callable(depends.dependency), (
depends.dependency "A parameter-less dependency must have a callable dependency"
), "A parameter-less dependency must have a callable dependency" )
return get_sub_dependant(depends=depends, dependency=depends.dependency, path=path) return get_sub_dependant(depends=depends, dependency=depends.dependency, path=path)
@ -302,9 +302,9 @@ def get_dependant(
type_annotation=param_details.type_annotation, type_annotation=param_details.type_annotation,
dependant=dependant, dependant=dependant,
): ):
assert ( assert param_details.field is None, (
param_details.field is None f"Cannot specify multiple FastAPI annotations for {param_name!r}"
), f"Cannot specify multiple FastAPI annotations for {param_name!r}" )
continue continue
assert param_details.field is not None assert param_details.field is not None
if isinstance(param_details.field.field_info, params.Body): if isinstance(param_details.field.field_info, params.Body):
@ -439,9 +439,9 @@ def analyze_param(
), ),
): ):
assert depends is None, f"Cannot specify `Depends` for type {type_annotation!r}" assert depends is None, f"Cannot specify `Depends` for type {type_annotation!r}"
assert ( assert field_info is None, (
field_info is None f"Cannot specify FastAPI annotation for type {type_annotation!r}"
), f"Cannot specify FastAPI annotation for type {type_annotation!r}" )
# Handle default assignations, neither field_info nor depends was not found in Annotated nor default value # Handle default assignations, neither field_info nor depends was not found in Annotated nor default value
elif field_info is None and depends is None: elif field_info is None and depends is None:
default_value = value if value is not inspect.Signature.empty else RequiredParam default_value = value if value is not inspect.Signature.empty else RequiredParam
@ -449,15 +449,15 @@ def analyze_param(
# We might check here that `default_value is RequiredParam`, but the fact is that the same # We might check here that `default_value is RequiredParam`, but the fact is that the same
# parameter might sometimes be a path parameter and sometimes not. See # parameter might sometimes be a path parameter and sometimes not. See
# `tests/test_infer_param_optionality.py` for an example. # `tests/test_infer_param_optionality.py` for an example.
field_info = params.Path(annotation=type_annotation) field_info = params.Path(annotation=use_annotation)
elif is_uploadfile_or_nonable_uploadfile_annotation( elif is_uploadfile_or_nonable_uploadfile_annotation(
type_annotation type_annotation
) or is_uploadfile_sequence_annotation(type_annotation): ) or is_uploadfile_sequence_annotation(type_annotation):
field_info = params.File(annotation=type_annotation, default=default_value) field_info = params.File(annotation=use_annotation, default=default_value)
elif not field_annotation_is_scalar(annotation=type_annotation): elif not field_annotation_is_scalar(annotation=type_annotation):
field_info = params.Body(annotation=type_annotation, default=default_value) field_info = params.Body(annotation=use_annotation, default=default_value)
else: else:
field_info = params.Query(annotation=type_annotation, default=default_value) field_info = params.Query(annotation=use_annotation, default=default_value)
field = None field = None
# It's a field_info, not a dependency # It's a field_info, not a dependency
@ -494,9 +494,9 @@ def analyze_param(
field_info=field_info, field_info=field_info,
) )
if is_path_param: if is_path_param:
assert is_scalar_field( assert is_scalar_field(field=field), (
field=field "Path params must be of one of the supported types"
), "Path params must be of one of the supported types" )
elif isinstance(field_info, params.Query): elif isinstance(field_info, params.Query):
assert ( assert (
is_scalar_field(field) is_scalar_field(field)
@ -521,9 +521,9 @@ def add_param_to_fields(*, field: ModelField, dependant: Dependant) -> None:
elif field_info_in == params.ParamTypes.header: elif field_info_in == params.ParamTypes.header:
dependant.header_params.append(field) dependant.header_params.append(field)
else: else:
assert ( assert field_info_in == params.ParamTypes.cookie, (
field_info_in == params.ParamTypes.cookie f"non-body parameters must be in path, query, header or cookie: {field.name}"
), f"non-body parameters must be in path, query, header or cookie: {field.name}" )
dependant.cookie_params.append(field) dependant.cookie_params.append(field)
@ -782,9 +782,9 @@ def request_params_to_args(
if single_not_embedded_field: if single_not_embedded_field:
field_info = first_field.field_info field_info = first_field.field_info
assert isinstance( assert isinstance(field_info, params.Param), (
field_info, params.Param "Params must be subclasses of Param"
), "Params must be subclasses of Param" )
loc: Tuple[str, ...] = (field_info.in_.value,) loc: Tuple[str, ...] = (field_info.in_.value,)
v_, errors_ = _validate_value_with_model_field( v_, errors_ = _validate_value_with_model_field(
field=first_field, value=params_to_process, values=values, loc=loc field=first_field, value=params_to_process, values=values, loc=loc
@ -794,9 +794,9 @@ def request_params_to_args(
for field in fields: for field in fields:
value = _get_multidict_value(field, received_params) value = _get_multidict_value(field, received_params)
field_info = field.field_info field_info = field.field_info
assert isinstance( assert isinstance(field_info, params.Param), (
field_info, params.Param "Params must be subclasses of Param"
), "Params must be subclasses of Param" )
loc = (field_info.in_.value, field.alias) loc = (field_info.in_.value, field.alias)
v_, errors_ = _validate_value_with_model_field( v_, errors_ = _validate_value_with_model_field(
field=field, value=value, values=values, loc=loc field=field, value=value, values=values, loc=loc

12
fastapi/openapi/utils.py

@ -364,9 +364,9 @@ def get_openapi_path(
openapi_response = operation_responses.setdefault( openapi_response = operation_responses.setdefault(
status_code_key, {} status_code_key, {}
) )
assert isinstance( assert isinstance(process_response, dict), (
process_response, dict "An additional response must be a dict"
), "An additional response must be a dict" )
field = route.response_fields.get(additional_status_code) field = route.response_fields.get(additional_status_code)
additional_field_schema: Optional[Dict[str, Any]] = None additional_field_schema: Optional[Dict[str, Any]] = None
if field: if field:
@ -434,9 +434,9 @@ def get_fields_from_routes(
route, routing.APIRoute route, routing.APIRoute
): ):
if route.body_field: if route.body_field:
assert isinstance( assert isinstance(route.body_field, ModelField), (
route.body_field, ModelField "A request body must be a Pydantic Field"
), "A request body must be a Pydantic Field" )
body_fields_from_routes.append(route.body_field) body_fields_from_routes.append(route.body_field)
if route.response_field: if route.response_field:
responses_from_routes.append(route.response_field) responses_from_routes.append(route.response_field)

24
fastapi/routing.py

@ -504,9 +504,9 @@ class APIRoute(routing.Route):
status_code = int(status_code) status_code = int(status_code)
self.status_code = status_code self.status_code = status_code
if self.response_model: if self.response_model:
assert is_body_allowed_for_status_code( assert is_body_allowed_for_status_code(status_code), (
status_code f"Status code {status_code} must not have a response body"
), f"Status code {status_code} must not have a response body" )
response_name = "Response_" + self.unique_id response_name = "Response_" + self.unique_id
self.response_field = create_model_field( self.response_field = create_model_field(
name=response_name, name=response_name,
@ -537,9 +537,9 @@ class APIRoute(routing.Route):
assert isinstance(response, dict), "An additional response must be a dict" assert isinstance(response, dict), "An additional response must be a dict"
model = response.get("model") model = response.get("model")
if model: if model:
assert is_body_allowed_for_status_code( assert is_body_allowed_for_status_code(additional_status_code), (
additional_status_code f"Status code {additional_status_code} must not have a response body"
), f"Status code {additional_status_code} must not have a response body" )
response_name = f"Response_{additional_status_code}_{self.unique_id}" response_name = f"Response_{additional_status_code}_{self.unique_id}"
response_field = create_model_field( response_field = create_model_field(
name=response_name, type_=model, mode="serialization" name=response_name, type_=model, mode="serialization"
@ -844,9 +844,9 @@ class APIRouter(routing.Router):
) )
if prefix: if prefix:
assert prefix.startswith("/"), "A path prefix must start with '/'" assert prefix.startswith("/"), "A path prefix must start with '/'"
assert not prefix.endswith( assert not prefix.endswith("/"), (
"/" "A path prefix must not end with '/', as the routes will start with '/'"
), "A path prefix must not end with '/', as the routes will start with '/'" )
self.prefix = prefix self.prefix = prefix
self.tags: List[Union[str, Enum]] = tags or [] self.tags: List[Union[str, Enum]] = tags or []
self.dependencies = list(dependencies or []) self.dependencies = list(dependencies or [])
@ -1256,9 +1256,9 @@ class APIRouter(routing.Router):
""" """
if prefix: if prefix:
assert prefix.startswith("/"), "A path prefix must start with '/'" assert prefix.startswith("/"), "A path prefix must start with '/'"
assert not prefix.endswith( assert not prefix.endswith("/"), (
"/" "A path prefix must not end with '/', as the routes will start with '/'"
), "A path prefix must not end with '/', as the routes will start with '/'" )
else: else:
for r in router.routes: for r in router.routes:
path = getattr(r, "path") # noqa: B009 path = getattr(r, "path") # noqa: B009

2
requirements-docs-tests.txt

@ -1,4 +1,4 @@
# For mkdocstrings and tests # For mkdocstrings and tests
httpx >=0.23.0,<0.28.0 httpx >=0.23.0,<0.28.0
# For linting and generating docs versions # For linting and generating docs versions
ruff ==0.6.4 ruff ==0.9.4

2
requirements-docs.txt

@ -14,6 +14,6 @@ cairosvg==2.7.1
mkdocstrings[python]==0.26.1 mkdocstrings[python]==0.26.1
griffe-typingdoc==0.2.7 griffe-typingdoc==0.2.7
# For griffe, it formats with black # For griffe, it formats with black
black==24.10.0 black==25.1.0
mkdocs-macros-plugin==1.3.7 mkdocs-macros-plugin==1.3.7
markdown-include-variants==0.0.4 markdown-include-variants==0.0.4

2
requirements-tests.txt

@ -4,7 +4,7 @@ pytest >=7.1.3,<9.0.0
coverage[toml] >= 6.5.0,< 8.0 coverage[toml] >= 6.5.0,< 8.0
mypy ==1.8.0 mypy ==1.8.0
dirty-equals ==0.8.0 dirty-equals ==0.8.0
sqlmodel==0.0.22 sqlmodel==0.0.23
flask >=1.1.2,<4.0.0 flask >=1.1.2,<4.0.0
anyio[trio] >=3.2.1,<5.0.0 anyio[trio] >=3.2.1,<5.0.0
PyJWT==2.8.0 PyJWT==2.8.0

12
scripts/translate.py

@ -38,9 +38,9 @@ def get_langs() -> dict[str, str]:
def generate_lang_path(*, lang: str, path: Path) -> Path: def generate_lang_path(*, lang: str, path: Path) -> Path:
en_docs_path = Path("docs/en/docs") en_docs_path = Path("docs/en/docs")
assert str(path).startswith( assert str(path).startswith(str(en_docs_path)), (
str(en_docs_path) f"Path must be inside {en_docs_path}"
), f"Path must be inside {en_docs_path}" )
lang_docs_path = Path(f"docs/{lang}/docs") lang_docs_path = Path(f"docs/{lang}/docs")
out_path = Path(str(path).replace(str(en_docs_path), str(lang_docs_path))) out_path = Path(str(path).replace(str(en_docs_path), str(lang_docs_path)))
return out_path return out_path
@ -56,9 +56,9 @@ def translate_page(*, lang: str, path: Path) -> None:
lang_prompt_content = lang_prompt_path.read_text() lang_prompt_content = lang_prompt_path.read_text()
en_docs_path = Path("docs/en/docs") en_docs_path = Path("docs/en/docs")
assert str(path).startswith( assert str(path).startswith(str(en_docs_path)), (
str(en_docs_path) f"Path must be inside {en_docs_path}"
), f"Path must be inside {en_docs_path}" )
out_path = generate_lang_path(lang=lang, path=path) out_path = generate_lang_path(lang=lang, path=path)
out_path.parent.mkdir(parents=True, exist_ok=True) out_path.parent.mkdir(parents=True, exist_ok=True)
original_content = path.read_text() original_content = path.read_text()

22
tests/test_analyze_param.py

@ -1,22 +0,0 @@
from inspect import signature
from fastapi.dependencies.utils import ParamDetails, analyze_param
from pydantic import Field
from typing_extensions import Annotated
from .utils import needs_pydanticv2
def func(user: Annotated[int, Field(strict=True)]): ...
@needs_pydanticv2
def test_analyze_param():
result = analyze_param(
param_name="user",
annotation=signature(func).parameters["user"].annotation,
value=object(),
is_path_param=False,
)
assert isinstance(result, ParamDetails)
assert result.field.field_info.annotation is int

6
tests/test_enforce_once_required_parameter.py

@ -48,7 +48,7 @@ expected_schema = {
"type": "array", "type": "array",
}, },
"msg": {"title": "Message", "type": "string"}, "msg": {"title": "Message", "type": "string"},
"type": {"title": "Error " "Type", "type": "string"}, "type": {"title": "Error Type", "type": "string"},
}, },
"required": ["loc", "msg", "type"], "required": ["loc", "msg", "type"],
"title": "ValidationError", "title": "ValidationError",
@ -73,7 +73,7 @@ expected_schema = {
"responses": { "responses": {
"200": { "200": {
"content": {"application/json": {"schema": {}}}, "content": {"application/json": {"schema": {}}},
"description": "Successful " "Response", "description": "Successful Response",
}, },
"422": { "422": {
"content": { "content": {
@ -83,7 +83,7 @@ expected_schema = {
} }
} }
}, },
"description": "Validation " "Error", "description": "Validation Error",
}, },
}, },
"summary": "Foo Handler", "summary": "Foo Handler",

4
tests/test_generic_parameterless_depends.py

@ -55,7 +55,7 @@ def test_openapi_schema():
"responses": { "responses": {
"200": { "200": {
"content": {"application/json": {"schema": {}}}, "content": {"application/json": {"schema": {}}},
"description": "Successful " "Response", "description": "Successful Response",
} }
}, },
"summary": "A", "summary": "A",
@ -67,7 +67,7 @@ def test_openapi_schema():
"responses": { "responses": {
"200": { "200": {
"content": {"application/json": {"schema": {}}}, "content": {"application/json": {"schema": {}}},
"description": "Successful " "Response", "description": "Successful Response",
} }
}, },
"summary": "B", "summary": "B",

6
tests/test_repeated_dependency_schema.py

@ -41,7 +41,7 @@ schema = {
"type": "array", "type": "array",
}, },
"msg": {"title": "Message", "type": "string"}, "msg": {"title": "Message", "type": "string"},
"type": {"title": "Error " "Type", "type": "string"}, "type": {"title": "Error Type", "type": "string"},
}, },
"required": ["loc", "msg", "type"], "required": ["loc", "msg", "type"],
"title": "ValidationError", "title": "ValidationError",
@ -66,7 +66,7 @@ schema = {
"responses": { "responses": {
"200": { "200": {
"content": {"application/json": {"schema": {}}}, "content": {"application/json": {"schema": {}}},
"description": "Successful " "Response", "description": "Successful Response",
}, },
"422": { "422": {
"content": { "content": {
@ -76,7 +76,7 @@ schema = {
} }
} }
}, },
"description": "Validation " "Error", "description": "Validation Error",
}, },
}, },
"summary": "Get Deps", "summary": "Get Deps",

48
tests/test_tutorial/test_configure_swagger_ui/test_tutorial001.py

@ -8,31 +8,31 @@ client = TestClient(app)
def test_swagger_ui(): def test_swagger_ui():
response = client.get("/docs") response = client.get("/docs")
assert response.status_code == 200, response.text assert response.status_code == 200, response.text
assert ( assert '"syntaxHighlight": false' in response.text, (
'"syntaxHighlight": false' in response.text "syntaxHighlight should be included and converted to JSON"
), "syntaxHighlight should be included and converted to JSON" )
assert ( assert '"dom_id": "#swagger-ui"' in response.text, (
'"dom_id": "#swagger-ui"' in response.text "default configs should be preserved"
), "default configs should be preserved" )
assert "presets: [" in response.text, "default configs should be preserved" assert "presets: [" in response.text, "default configs should be preserved"
assert ( assert "SwaggerUIBundle.presets.apis," in response.text, (
"SwaggerUIBundle.presets.apis," in response.text "default configs should be preserved"
), "default configs should be preserved" )
assert ( assert "SwaggerUIBundle.SwaggerUIStandalonePreset" in response.text, (
"SwaggerUIBundle.SwaggerUIStandalonePreset" in response.text "default configs should be preserved"
), "default configs should be preserved" )
assert ( assert '"layout": "BaseLayout",' in response.text, (
'"layout": "BaseLayout",' in response.text "default configs should be preserved"
), "default configs should be preserved" )
assert ( assert '"deepLinking": true,' in response.text, (
'"deepLinking": true,' in response.text "default configs should be preserved"
), "default configs should be preserved" )
assert ( assert '"showExtensions": true,' in response.text, (
'"showExtensions": true,' in response.text "default configs should be preserved"
), "default configs should be preserved" )
assert ( assert '"showCommonExtensions": true,' in response.text, (
'"showCommonExtensions": true,' in response.text "default configs should be preserved"
), "default configs should be preserved" )
def test_get_users(): def test_get_users():

54
tests/test_tutorial/test_configure_swagger_ui/test_tutorial002.py

@ -8,34 +8,34 @@ client = TestClient(app)
def test_swagger_ui(): def test_swagger_ui():
response = client.get("/docs") response = client.get("/docs")
assert response.status_code == 200, response.text assert response.status_code == 200, response.text
assert ( assert '"syntaxHighlight": false' not in response.text, (
'"syntaxHighlight": false' not in response.text "not used parameters should not be included"
), "not used parameters should not be included" )
assert ( assert '"syntaxHighlight": {"theme": "obsidian"}' in response.text, (
'"syntaxHighlight": {"theme": "obsidian"}' in response.text "parameters with middle dots should be included in a JSON compatible way"
), "parameters with middle dots should be included in a JSON compatible way" )
assert ( assert '"dom_id": "#swagger-ui"' in response.text, (
'"dom_id": "#swagger-ui"' in response.text "default configs should be preserved"
), "default configs should be preserved" )
assert "presets: [" in response.text, "default configs should be preserved" assert "presets: [" in response.text, "default configs should be preserved"
assert ( assert "SwaggerUIBundle.presets.apis," in response.text, (
"SwaggerUIBundle.presets.apis," in response.text "default configs should be preserved"
), "default configs should be preserved" )
assert ( assert "SwaggerUIBundle.SwaggerUIStandalonePreset" in response.text, (
"SwaggerUIBundle.SwaggerUIStandalonePreset" in response.text "default configs should be preserved"
), "default configs should be preserved" )
assert ( assert '"layout": "BaseLayout",' in response.text, (
'"layout": "BaseLayout",' in response.text "default configs should be preserved"
), "default configs should be preserved" )
assert ( assert '"deepLinking": true,' in response.text, (
'"deepLinking": true,' in response.text "default configs should be preserved"
), "default configs should be preserved" )
assert ( assert '"showExtensions": true,' in response.text, (
'"showExtensions": true,' in response.text "default configs should be preserved"
), "default configs should be preserved" )
assert ( assert '"showCommonExtensions": true,' in response.text, (
'"showCommonExtensions": true,' in response.text "default configs should be preserved"
), "default configs should be preserved" )
def test_get_users(): def test_get_users():

54
tests/test_tutorial/test_configure_swagger_ui/test_tutorial003.py

@ -8,34 +8,34 @@ client = TestClient(app)
def test_swagger_ui(): def test_swagger_ui():
response = client.get("/docs") response = client.get("/docs")
assert response.status_code == 200, response.text assert response.status_code == 200, response.text
assert ( assert '"deepLinking": false,' in response.text, (
'"deepLinking": false,' in response.text "overridden configs should be preserved"
), "overridden configs should be preserved" )
assert ( assert '"deepLinking": true' not in response.text, (
'"deepLinking": true' not in response.text "overridden configs should not include the old value"
), "overridden configs should not include the old value" )
assert ( assert '"syntaxHighlight": false' not in response.text, (
'"syntaxHighlight": false' not in response.text "not used parameters should not be included"
), "not used parameters should not be included" )
assert ( assert '"dom_id": "#swagger-ui"' in response.text, (
'"dom_id": "#swagger-ui"' in response.text "default configs should be preserved"
), "default configs should be preserved" )
assert "presets: [" in response.text, "default configs should be preserved" assert "presets: [" in response.text, "default configs should be preserved"
assert ( assert "SwaggerUIBundle.presets.apis," in response.text, (
"SwaggerUIBundle.presets.apis," in response.text "default configs should be preserved"
), "default configs should be preserved" )
assert ( assert "SwaggerUIBundle.SwaggerUIStandalonePreset" in response.text, (
"SwaggerUIBundle.SwaggerUIStandalonePreset" in response.text "default configs should be preserved"
), "default configs should be preserved" )
assert ( assert '"layout": "BaseLayout",' in response.text, (
'"layout": "BaseLayout",' in response.text "default configs should be preserved"
), "default configs should be preserved" )
assert ( assert '"showExtensions": true,' in response.text, (
'"showExtensions": true,' in response.text "default configs should be preserved"
), "default configs should be preserved" )
assert ( assert '"showCommonExtensions": true,' in response.text, (
'"showCommonExtensions": true,' in response.text "default configs should be preserved"
), "default configs should be preserved" )
def test_get_users(): def test_get_users():

143
tests/test_tutorial/test_query_params_str_validations/test_tutorial015.py

@ -0,0 +1,143 @@
import importlib
import pytest
from dirty_equals import IsStr
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
from ...utils import needs_py39, needs_py310, needs_pydanticv2
@pytest.fixture(
name="client",
params=[
pytest.param("tutorial015_an", marks=needs_pydanticv2),
pytest.param("tutorial015_an_py310", marks=(needs_py310, needs_pydanticv2)),
pytest.param("tutorial015_an_py39", marks=(needs_py39, needs_pydanticv2)),
],
)
def get_client(request: pytest.FixtureRequest):
mod = importlib.import_module(
f"docs_src.query_params_str_validations.{request.param}"
)
client = TestClient(mod.app)
return client
def test_get_random_item(client: TestClient):
response = client.get("/items")
assert response.status_code == 200, response.text
assert response.json() == {"id": IsStr(), "name": IsStr()}
def test_get_item(client: TestClient):
response = client.get("/items?id=isbn-9781529046137")
assert response.status_code == 200, response.text
assert response.json() == {
"id": "isbn-9781529046137",
"name": "The Hitchhiker's Guide to the Galaxy",
}
def test_get_item_does_not_exist(client: TestClient):
response = client.get("/items?id=isbn-nope")
assert response.status_code == 200, response.text
assert response.json() == {"id": "isbn-nope", "name": None}
def test_get_invalid_item(client: TestClient):
response = client.get("/items?id=wtf-yes")
assert response.status_code == 422, response.text
assert response.json() == snapshot(
{
"detail": [
{
"type": "value_error",
"loc": ["query", "id"],
"msg": 'Value error, Invalid ID format, it must start with "isbn-" or "imdb-"',
"input": "wtf-yes",
"ctx": {"error": {}},
}
]
}
)
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": "id",
"in": "query",
"required": False,
"schema": {
"anyOf": [{"type": "string"}, {"type": "null"}],
"title": "Id",
},
}
],
"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",
},
}
},
}
)

6
tests/test_tutorial/test_sql_databases/test_tutorial002.py

@ -71,9 +71,9 @@ def test_crud_app(client: TestClient):
assert response.json() == snapshot( assert response.json() == snapshot(
{"age": 30, "id": IsInt(), "name": "Dead Pond"} {"age": 30, "id": IsInt(), "name": "Dead Pond"}
) )
assert ( assert response.json()["id"] != 9000, (
response.json()["id"] != 9000 "The ID should be generated by the database"
), "The ID should be generated by the database" )
# Read a hero # Read a hero
hero_id = response.json()["id"] hero_id = response.json()["id"]

Loading…
Cancel
Save