From 89e0c105474075f5e6b50192da82d7189e5d6617 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sat, 1 Mar 2025 18:19:17 +0100 Subject: [PATCH 01/22] =?UTF-8?q?=F0=9F=91=A5=20Update=20FastAPI=20People?= =?UTF-8?q?=20-=20Sponsors=20(#13433)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: github-actions --- docs/en/data/github_sponsors.yml | 177 ++++++++++++++----------------- 1 file changed, 81 insertions(+), 96 deletions(-) diff --git a/docs/en/data/github_sponsors.yml b/docs/en/data/github_sponsors.yml index feb4e727f..805d72b73 100644 --- a/docs/en/data/github_sponsors.yml +++ b/docs/en/data/github_sponsors.yml @@ -1,10 +1,10 @@ sponsors: -- - login: bump-sh - avatarUrl: https://avatars.githubusercontent.com/u/33217836?v=4 - url: https://github.com/bump-sh - - login: renderinc +- - login: renderinc avatarUrl: https://avatars.githubusercontent.com/u/36424661?v=4 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 avatarUrl: https://avatars.githubusercontent.com/u/79945230?v=4 url: https://github.com/Nixtla @@ -23,6 +23,9 @@ sponsors: - login: zuplo avatarUrl: https://avatars.githubusercontent.com/u/85497839?v=4 url: https://github.com/zuplo + - login: coderabbitai + avatarUrl: https://avatars.githubusercontent.com/u/132028505?v=4 + url: https://github.com/coderabbitai - login: porter-dev avatarUrl: https://avatars.githubusercontent.com/u/62078005?v=4 url: https://github.com/porter-dev @@ -59,6 +62,9 @@ sponsors: - login: Ponte-Energy-Partners avatarUrl: https://avatars.githubusercontent.com/u/114745848?v=4 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 avatarUrl: https://avatars.githubusercontent.com/u/57932412?v=4 url: https://github.com/BoostryJP @@ -80,9 +86,6 @@ sponsors: - login: yasyf avatarUrl: https://avatars.githubusercontent.com/u/709645?u=f36736b3c6a85f578886ecc42a740e7b436e7a01&v=4 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 avatarUrl: https://avatars.githubusercontent.com/u/62146168?v=4 url: https://github.com/primer-io @@ -98,24 +101,18 @@ sponsors: - - login: samuelcolvin avatarUrl: https://avatars.githubusercontent.com/u/4039449?u=42eb3b833047c8c4b4f647a031eaef148c16d93f&v=4 url: https://github.com/samuelcolvin - - login: ProteinQure - avatarUrl: https://avatars.githubusercontent.com/u/33707203?v=4 - url: https://github.com/ProteinQure + - login: vincentkoc + avatarUrl: https://avatars.githubusercontent.com/u/25068?u=fbd5b2d51142daa4bdbc21e21953a3b8b8188a4a&v=4 + url: https://github.com/vincentkoc - login: ddilidili avatarUrl: https://avatars.githubusercontent.com/u/42176885?u=c0a849dde06987434653197b5f638d3deb55fc6c&v=4 url: https://github.com/ddilidili - login: otosky avatarUrl: https://avatars.githubusercontent.com/u/42260747?u=69d089387c743d89427aa4ad8740cfb34045a9e0&v=4 url: https://github.com/otosky - - login: khadrawy - avatarUrl: https://avatars.githubusercontent.com/u/13686061?u=59f25ef42ecf04c22657aac4238ce0e2d3d30304&v=4 - url: https://github.com/khadrawy - - login: mjohnsey - avatarUrl: https://avatars.githubusercontent.com/u/16784016?u=38fad2e6b411244560b3af99c5f5a4751bc81865&v=4 - url: https://github.com/mjohnsey - - login: ashi-agrawal - avatarUrl: https://avatars.githubusercontent.com/u/17105294?u=99c7a854035e5398d8e7b674f2d42baae6c957f8&v=4 - url: https://github.com/ashi-agrawal + - login: ramonalmeidam + avatarUrl: https://avatars.githubusercontent.com/u/45269580?u=3358750b3a5854d7c3ed77aaca7dd20a0f529d32&v=4 + url: https://github.com/ramonalmeidam - login: sepsi77 avatarUrl: https://avatars.githubusercontent.com/u/18682303?v=4 url: https://github.com/sepsi77 @@ -140,11 +137,17 @@ sponsors: - login: Leay15 avatarUrl: https://avatars.githubusercontent.com/u/32212558?u=c4aa9c1737e515959382a5515381757b1fd86c53&v=4 url: https://github.com/Leay15 + - login: BoYanZh + avatarUrl: https://avatars.githubusercontent.com/u/32470225?u=55b174d080382822759d74307f8a0355fa86e808&v=4 + url: https://github.com/BoYanZh - login: ygorpontelo avatarUrl: https://avatars.githubusercontent.com/u/32963605?u=35f7103f9c4c4c2589ae5737ee882e9375ef072e&v=4 url: https://github.com/ygorpontelo + - login: ProteinQure + avatarUrl: https://avatars.githubusercontent.com/u/33707203?v=4 + url: https://github.com/ProteinQure - login: chickenandstats - avatarUrl: https://avatars.githubusercontent.com/u/79477966?v=4 + avatarUrl: https://avatars.githubusercontent.com/u/79477966?u=ae2b894aa954070db1d7830dab99b49eba4e4567&v=4 url: https://github.com/chickenandstats - login: kaoru0310 avatarUrl: https://avatars.githubusercontent.com/u/80977929?u=1b61d10142b490e56af932ddf08a390fae8ee94f&v=4 @@ -164,12 +167,6 @@ sponsors: - login: logic-automation avatarUrl: https://avatars.githubusercontent.com/u/144732884?v=4 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 avatarUrl: https://avatars.githubusercontent.com/u/53104118?v=4 url: https://github.com/roboflow @@ -185,12 +182,6 @@ sponsors: - login: patricioperezv avatarUrl: https://avatars.githubusercontent.com/u/73832292?u=5f471f156e19ee7920e62ae0f4a47b95580e61cf&v=4 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 avatarUrl: https://avatars.githubusercontent.com/u/1362607?u=9bf1e0e520cccc547c046610c468ce6115bbcf9f&v=4 url: https://github.com/dodo5522 @@ -218,9 +209,15 @@ sponsors: - login: anomaly avatarUrl: https://avatars.githubusercontent.com/u/3654837?v=4 url: https://github.com/anomaly - - login: vincentkoc - avatarUrl: https://avatars.githubusercontent.com/u/25068?u=fbd5b2d51142daa4bdbc21e21953a3b8b8188a4a&v=4 - url: https://github.com/vincentkoc + - login: gorhack + avatarUrl: https://avatars.githubusercontent.com/u/4141690?u=ec119ebc4bdf00a7bc84657a71aa17834f4f27f3&v=4 + url: https://github.com/gorhack + - login: Ryandaydev + avatarUrl: https://avatars.githubusercontent.com/u/4292423?u=48f68868db8886fce31a1d802c1003914c6cd7c6&v=4 + url: https://github.com/Ryandaydev + - login: jaredtrog + avatarUrl: https://avatars.githubusercontent.com/u/4381365?v=4 + url: https://github.com/jaredtrog - login: jstanden avatarUrl: https://avatars.githubusercontent.com/u/63288?u=c3658d57d2862c607a0e19c2101c3c51876e36ad&v=4 url: https://github.com/jstanden @@ -251,12 +248,12 @@ sponsors: - login: falkben avatarUrl: https://avatars.githubusercontent.com/u/653031?u=ad9838e089058c9e5a0bab94c0eec7cc181e0cd0&v=4 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 avatarUrl: https://avatars.githubusercontent.com/u/9167887?u=dccbea3327a57750923333d8ebf1a0b3f1948949&v=4 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 avatarUrl: https://avatars.githubusercontent.com/u/11562137?u=dc01daafb354135603a263729e3d26d939c0c452&v=4 url: https://github.com/wdwinslow @@ -272,21 +269,18 @@ sponsors: - login: dannywade avatarUrl: https://avatars.githubusercontent.com/u/13680237?u=418ee985bd41577b20fde81417fb2d901e875e8a&v=4 url: https://github.com/dannywade - - login: gorhack - avatarUrl: https://avatars.githubusercontent.com/u/4141690?u=ec119ebc4bdf00a7bc84657a71aa17834f4f27f3&v=4 - url: https://github.com/gorhack - - login: Ryandaydev - avatarUrl: https://avatars.githubusercontent.com/u/4292423?u=48f68868db8886fce31a1d802c1003914c6cd7c6&v=4 - url: https://github.com/Ryandaydev - - login: jaredtrog - avatarUrl: https://avatars.githubusercontent.com/u/4381365?v=4 - url: https://github.com/jaredtrog + - login: khadrawy + avatarUrl: https://avatars.githubusercontent.com/u/13686061?u=59f25ef42ecf04c22657aac4238ce0e2d3d30304&v=4 + url: https://github.com/khadrawy + - login: mjohnsey + avatarUrl: https://avatars.githubusercontent.com/u/16784016?u=38fad2e6b411244560b3af99c5f5a4751bc81865&v=4 + url: https://github.com/mjohnsey + - login: ashi-agrawal + avatarUrl: https://avatars.githubusercontent.com/u/17105294?u=99c7a854035e5398d8e7b674f2d42baae6c957f8&v=4 + url: https://github.com/ashi-agrawal - login: oliverxchen avatarUrl: https://avatars.githubusercontent.com/u/4471774?u=534191f25e32eeaadda22dfab4b0a428733d5489&v=4 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 avatarUrl: https://avatars.githubusercontent.com/u/5481618?u=513a26b02a39e7a28d587cd37c6cc877ea368e6e&v=4 url: https://github.com/ternaus @@ -308,9 +302,6 @@ sponsors: - - login: pawamoy avatarUrl: https://avatars.githubusercontent.com/u/3999221?u=b030e4c89df2f3a36bc4710b925bdeb6745c9856&v=4 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 avatarUrl: https://avatars.githubusercontent.com/u/34930566?u=db5e6f4f87836cad26c2aa90ce390ce49041c5a9&v=4 url: https://github.com/bnkc @@ -323,15 +314,12 @@ sponsors: - login: mobyw avatarUrl: https://avatars.githubusercontent.com/u/44370805?v=4 url: https://github.com/mobyw - - login: PelicanQ - avatarUrl: https://avatars.githubusercontent.com/u/77930606?v=4 - url: https://github.com/PelicanQ - - login: TheR1D - avatarUrl: https://avatars.githubusercontent.com/u/16740832?u=b0dfdbdb27b79729430c71c6128962f77b7b53f7&v=4 - url: https://github.com/TheR1D - - login: joshuatz - avatarUrl: https://avatars.githubusercontent.com/u/17817563?u=f1bf05b690d1fc164218f0b420cdd3acb7913e21&v=4 - url: https://github.com/joshuatz + - login: ArtyomVancyan + avatarUrl: https://avatars.githubusercontent.com/u/44609997?v=4 + url: https://github.com/ArtyomVancyan + - login: caviri + avatarUrl: https://avatars.githubusercontent.com/u/45425937?u=4e14bd64282bad8f385eafbdb004b5a279366d6e&v=4 + url: https://github.com/caviri - login: SebTota avatarUrl: https://avatars.githubusercontent.com/u/25122511?v=4 url: https://github.com/SebTota @@ -350,12 +338,9 @@ sponsors: - login: dvlpjrs avatarUrl: https://avatars.githubusercontent.com/u/32254642?u=fbd6ad0324d4f1eb6231cf775be1c7bd4404e961&v=4 url: https://github.com/dvlpjrs - - login: ArtyomVancyan - avatarUrl: https://avatars.githubusercontent.com/u/44609997?v=4 - url: https://github.com/ArtyomVancyan - - login: caviri - avatarUrl: https://avatars.githubusercontent.com/u/45425937?u=4e14bd64282bad8f385eafbdb004b5a279366d6e&v=4 - url: https://github.com/caviri + - login: engineerjoe440 + avatarUrl: https://avatars.githubusercontent.com/u/33275230?u=eb223cad27017bb1e936ee9b429b450d092d0236&v=4 + url: https://github.com/engineerjoe440 - login: hgalytoby avatarUrl: https://avatars.githubusercontent.com/u/50397689?u=62c7ff3519858423579676cd0efbd7e3f1ffe63a&v=4 url: https://github.com/hgalytoby @@ -368,9 +353,9 @@ sponsors: - login: PunRabbit avatarUrl: https://avatars.githubusercontent.com/u/70463212?u=1a835cfbc99295a60c8282f6aa6199d1b42241a5&v=4 url: https://github.com/PunRabbit - - login: tochikuji - avatarUrl: https://avatars.githubusercontent.com/u/851759?v=4 - url: https://github.com/tochikuji + - login: PelicanQ + avatarUrl: https://avatars.githubusercontent.com/u/77930606?v=4 + url: https://github.com/PelicanQ - login: browniebroke avatarUrl: https://avatars.githubusercontent.com/u/861044?u=5abfca5588f3e906b31583d7ee62f6de4b68aa24&v=4 url: https://github.com/browniebroke @@ -389,9 +374,6 @@ sponsors: - login: Alisa-lisa avatarUrl: https://avatars.githubusercontent.com/u/4137964?u=e7e393504f554f4ff15863a1e01a5746863ef9ce&v=4 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 avatarUrl: https://avatars.githubusercontent.com/u/113563?u=ed1dc79de72f93bd78581f88ebc6952b62f472da&v=4 url: https://github.com/ddanier @@ -404,15 +386,9 @@ sponsors: - login: ceb10n avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4 url: https://github.com/ceb10n - - login: eteq - avatarUrl: https://avatars.githubusercontent.com/u/346587?v=4 - url: https://github.com/eteq - - 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: tochikuji + avatarUrl: https://avatars.githubusercontent.com/u/851759?v=4 + url: https://github.com/tochikuji - login: msehnout avatarUrl: https://avatars.githubusercontent.com/u/9369632?u=8c988f1b008a3f601385a3616f9327820f66e3a5&v=4 url: https://github.com/msehnout @@ -420,7 +396,7 @@ sponsors: avatarUrl: https://avatars.githubusercontent.com/u/9462045?u=a80a7bb349555b277645632ed66639ff43400614&v=4 url: https://github.com/xncbf - 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 - login: hard-coders avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4 @@ -434,18 +410,18 @@ sponsors: - login: pheanex avatarUrl: https://avatars.githubusercontent.com/u/10408624?u=5b6bab6ee174aa6e991333e06eb29f628741013d&v=4 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 avatarUrl: https://avatars.githubusercontent.com/u/10934846?u=1ef43e075ddc87bd1178372bf4d95ee6175cae27&v=4 url: https://github.com/Zuzah - login: artempronevskiy avatarUrl: https://avatars.githubusercontent.com/u/12235104?u=03df6e1e55c9c6fe5d230adabb8dd7d43d8bbe8f&v=4 url: https://github.com/artempronevskiy - - login: Graeme22 - avatarUrl: https://avatars.githubusercontent.com/u/4185684?u=498182a42300d7bcd4de1215190cb17eb501136c&v=4 - url: https://github.com/Graeme22 + - login: TheR1D + avatarUrl: https://avatars.githubusercontent.com/u/16740832?u=b0dfdbdb27b79729430c71c6128962f77b7b53f7&v=4 + url: https://github.com/TheR1D + - login: joshuatz + avatarUrl: https://avatars.githubusercontent.com/u/17817563?u=f1bf05b690d1fc164218f0b420cdd3acb7913e21&v=4 + url: https://github.com/joshuatz - login: danielunderwood avatarUrl: https://avatars.githubusercontent.com/u/4472301?v=4 url: https://github.com/danielunderwood @@ -470,6 +446,12 @@ sponsors: - login: harsh183 avatarUrl: https://avatars.githubusercontent.com/u/7780198?v=4 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 avatarUrl: https://avatars.githubusercontent.com/u/34173819?u=74958599695bf83ac9f1addd935a51548a10c6b0&v=4 url: https://github.com/larsyngvelundin @@ -479,6 +461,9 @@ sponsors: - login: rwxd avatarUrl: https://avatars.githubusercontent.com/u/40308458?u=cd04a39e3655923be4f25c2ba8a5a07b3da3230a&v=4 url: https://github.com/rwxd + - login: morzan1001 + avatarUrl: https://avatars.githubusercontent.com/u/47593005?u=c30ab7230f82a12a9b938dcb54f84a996931409a&v=4 + url: https://github.com/morzan1001 - login: sadikkuzu avatarUrl: https://avatars.githubusercontent.com/u/23168063?u=d179c06bb9f65c4167fcab118526819f8e0dac17&v=4 url: https://github.com/sadikkuzu @@ -488,12 +473,12 @@ sponsors: - login: FabulousCodingFox avatarUrl: https://avatars.githubusercontent.com/u/78906517?u=924a27cbee3db7e0ece5cc1509921402e1445e74&v=4 url: https://github.com/FabulousCodingFox - - login: gateremark - avatarUrl: https://avatars.githubusercontent.com/u/91592218?u=969314eb2cfb035196f4d19499ec6f5050d7583a&v=4 - url: https://github.com/gateremark - - login: morzan1001 - avatarUrl: https://avatars.githubusercontent.com/u/47593005?u=c30ab7230f82a12a9b938dcb54f84a996931409a&v=4 - url: https://github.com/morzan1001 + - login: anqorithm + avatarUrl: https://avatars.githubusercontent.com/u/61029571?u=468256fa4e2d9ce2870b608299724bebb7a33f18&v=4 + url: https://github.com/anqorithm + - login: Materacl + avatarUrl: https://avatars.githubusercontent.com/u/70155818?u=ae11d084518856127cca483816a91a187e3124ee&v=4 + url: https://github.com/Materacl - login: Toothwitch avatarUrl: https://avatars.githubusercontent.com/u/1710406?u=5eebb23b46cd26e48643b9e5179536cad491c17a&v=4 url: https://github.com/Toothwitch From 186544760a803b39895ad9a563d56646a334588c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sat, 1 Mar 2025 18:19:24 +0100 Subject: [PATCH 02/22] =?UTF-8?q?=F0=9F=91=A5=20Update=20FastAPI=20People?= =?UTF-8?q?=20-=20Contributors=20and=20Translators=20(#13432)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: github-actions --- docs/en/data/contributors.yml | 38 +++-- docs/en/data/translation_reviewers.yml | 199 ++++++++++++++++--------- docs/en/data/translators.yml | 56 ++++--- 3 files changed, 194 insertions(+), 99 deletions(-) diff --git a/docs/en/data/contributors.yml b/docs/en/data/contributors.yml index 0e1a6505b..c4364e923 100644 --- a/docs/en/data/contributors.yml +++ b/docs/en/data/contributors.yml @@ -1,11 +1,11 @@ tiangolo: login: tiangolo - count: 713 + count: 723 avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4 url: https://github.com/tiangolo dependabot: login: dependabot - count: 90 + count: 94 avatarUrl: https://avatars.githubusercontent.com/in/29110?v=4 url: https://github.com/apps/dependabot alejsdev: @@ -68,6 +68,11 @@ vishnuvskvkl: count: 8 avatarUrl: https://avatars.githubusercontent.com/u/84698110?u=8af5de0520dd4fa195f53c2850a26f57c0f6bc64&v=4 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: login: alissadb count: 6 @@ -88,16 +93,16 @@ waynerv: count: 5 avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4 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: login: krishnamadhavan count: 5 avatarUrl: https://avatars.githubusercontent.com/u/31798870?u=950693b28f3ae01105fd545c046e46ca3d31ab06&v=4 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: login: jekirl count: 4 @@ -121,7 +126,7 @@ adriangb: iudeen: login: iudeen 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 philipokiokio: login: philipokiokio @@ -211,7 +216,7 @@ TeoZosa: graingert: login: graingert 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 jaystone776: login: jaystone776 @@ -233,6 +238,11 @@ papb: count: 3 avatarUrl: https://avatars.githubusercontent.com/u/20914054?u=890511fae7ea90d887e2a65ce44a1775abba38d5&v=4 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: login: gitworkflows count: 3 @@ -468,11 +478,6 @@ yezz123: count: 2 avatarUrl: https://avatars.githubusercontent.com/u/52716203?u=d7062cbc6eb7671d5dc9cc0e32a24ae335e0f225&v=4 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: login: softwarebloat count: 2 @@ -518,3 +523,8 @@ DanielKusyDev: count: 2 avatarUrl: https://avatars.githubusercontent.com/u/36250676?u=2ea6114ff751fc48b55f231987a0e2582c6b1bd2&v=4 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 diff --git a/docs/en/data/translation_reviewers.yml b/docs/en/data/translation_reviewers.yml index 6f16893ba..1a3c12988 100644 --- a/docs/en/data/translation_reviewers.yml +++ b/docs/en/data/translation_reviewers.yml @@ -10,9 +10,14 @@ Xewus: url: https://github.com/Xewus ceb10n: login: ceb10n - count: 110 + count: 112 avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4 url: https://github.com/ceb10n +sodaMelon: + login: sodaMelon + count: 111 + avatarUrl: https://avatars.githubusercontent.com/u/66295123?u=be939db90f1119efee9e6110cc05066ff1f40f00&v=4 + url: https://github.com/sodaMelon tokusumi: login: tokusumi count: 104 @@ -28,31 +33,26 @@ hard-coders: count: 92 avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4 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: login: AlertRED count: 81 avatarUrl: https://avatars.githubusercontent.com/u/15695000?u=f5a4944c6df443030409c88da7d7fa0b7ead985c&v=4 url: https://github.com/AlertRED -nazarepiedady: - login: nazarepiedady - count: 81 - avatarUrl: https://avatars.githubusercontent.com/u/31008635?u=8dc25777dc9cb51fb0dbba2f137988953d330b78&v=4 - url: https://github.com/nazarepiedady -sodaMelon: - login: sodaMelon +alv2017: + login: alv2017 count: 81 - avatarUrl: https://avatars.githubusercontent.com/u/66295123?u=be939db90f1119efee9e6110cc05066ff1f40f00&v=4 - url: https://github.com/sodaMelon + avatarUrl: https://avatars.githubusercontent.com/u/31544722?v=4 + url: https://github.com/alv2017 Alexandrhub: login: Alexandrhub count: 68 avatarUrl: https://avatars.githubusercontent.com/u/119126536?u=9fc0d48f3307817bafecc5861eb2168401a6cb04&v=4 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: login: waynerv count: 63 @@ -68,6 +68,11 @@ mattwang44: count: 58 avatarUrl: https://avatars.githubusercontent.com/u/24987826?u=58e37fb3927b9124b458945ac4c97aa0f1062d85&v=4 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: login: Laineyzhang55 count: 48 @@ -88,11 +93,11 @@ alperiox: count: 42 avatarUrl: https://avatars.githubusercontent.com/u/34214152?u=2c5acad3461d4dbc2d48371ba86cac56ae9b25cc&v=4 url: https://github.com/alperiox -tiangolo: - login: tiangolo - count: 40 - avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=cb5d06e73a9e1998141b1641aa88e443c6717651&v=4 - url: https://github.com/tiangolo +rostik1410: + login: rostik1410 + count: 41 + avatarUrl: https://avatars.githubusercontent.com/u/11443899?u=e26a635c2ba220467b308a326a579b8ccf4a8701&v=4 + url: https://github.com/rostik1410 Winand: login: Winand count: 40 @@ -118,11 +123,31 @@ SwftAlpc: count: 36 avatarUrl: https://avatars.githubusercontent.com/u/52768429?u=6a3aa15277406520ad37f6236e89466ed44bc5b8&v=4 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: login: nilslindemann count: 35 avatarUrl: https://avatars.githubusercontent.com/u/6892179?u=1dca6a22195d6cd1ab20737c0e19a4c55d639472&v=4 url: https://github.com/nilslindemann +svlandeg: + login: svlandeg + count: 35 + avatarUrl: https://avatars.githubusercontent.com/u/8796347?u=556c97650c27021911b0b9447ec55e75987b0e8a&v=4 + url: https://github.com/svlandeg +Rishat-F: + login: Rishat-F + count: 35 + avatarUrl: https://avatars.githubusercontent.com/u/66554797?v=4 + url: https://github.com/Rishat-F rjNemo: login: rjNemo count: 34 @@ -143,11 +168,6 @@ romashevchenko: count: 32 avatarUrl: https://avatars.githubusercontent.com/u/132477732?v=4 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: login: wdh99 count: 31 @@ -208,6 +228,11 @@ junah201: count: 26 avatarUrl: https://avatars.githubusercontent.com/u/75025529?u=2451c256e888fa2a06bcfc0646d09b87ddb6a945&v=4 url: https://github.com/junah201 +mezgoodle: + login: mezgoodle + count: 26 + avatarUrl: https://avatars.githubusercontent.com/u/41520940?u=e871bc26734eb2436d98c19c3fb57a4773e13c24&v=4 + url: https://github.com/mezgoodle Vincy1230: login: Vincy1230 count: 26 @@ -248,11 +273,6 @@ wisderfin: count: 23 avatarUrl: https://avatars.githubusercontent.com/u/77553770?u=f3b00a26736ba664e9927a1116c6e8088295e073&v=4 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: login: AGolicyn count: 21 @@ -266,7 +286,7 @@ Attsun1031: ycd: login: ycd 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 delhi09: login: delhi09 @@ -283,26 +303,21 @@ DevDae: count: 20 avatarUrl: https://avatars.githubusercontent.com/u/87962045?u=08e10fa516e844934f4b3fc7c38b33c61697e4a1&v=4 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: login: sattosan count: 19 avatarUrl: https://avatars.githubusercontent.com/u/20574756?u=b0d8474d2938189c6954423ae8d81d91013f80a8&v=4 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: login: ComicShrimp count: 18 avatarUrl: https://avatars.githubusercontent.com/u/43503750?u=d2fbf412e7730183ce91686ca48d4147e1b7dc74&v=4 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: login: simatheone count: 18 @@ -473,11 +488,6 @@ kwang1215: count: 12 avatarUrl: https://avatars.githubusercontent.com/u/74170199?u=2a63ff6692119dde3f5e5693365b9fcd6f977b08&v=4 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: login: AdrianDeAnda count: 11 @@ -498,6 +508,11 @@ glsglsgls: count: 11 avatarUrl: https://avatars.githubusercontent.com/u/76133879?v=4 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: login: codespearhead count: 11 @@ -586,7 +601,7 @@ waketzheng: lucasbalieiro: login: lucasbalieiro 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 RunningIkkyu: login: RunningIkkyu @@ -648,6 +663,11 @@ Zhongheng-Cheng: count: 9 avatarUrl: https://avatars.githubusercontent.com/u/95612344?u=a0f7730a3cc7486827965e01a119ad610bda4b0a&v=4 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: login: dimaqq count: 8 @@ -683,11 +703,21 @@ KimJoonSeo: count: 8 avatarUrl: https://avatars.githubusercontent.com/u/17760162?u=a58cdc77ae1c069a64166f7ecc4d42eecfd9a468&v=4 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: login: camigomezdev count: 8 avatarUrl: https://avatars.githubusercontent.com/u/16061815?u=25b5ebc042fff53fa03dc107ded10e36b1b7a5b9&v=4 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: login: Serrones count: 7 @@ -843,6 +873,16 @@ bankofsardine: count: 6 avatarUrl: https://avatars.githubusercontent.com/u/44944207?u=0368e1b698ffab6bf29e202f9fd2dddd352429f1&v=4 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: login: rsip22 count: 5 @@ -856,7 +896,7 @@ jessicapaz: mohsen-mahmoodi: login: mohsen-mahmoodi 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 jeesang7: login: jeesang7 @@ -958,11 +998,11 @@ devluisrodrigues: count: 5 avatarUrl: https://avatars.githubusercontent.com/u/103431660?u=d9674a3249edc4601d2c712cdebf899918503c3a&v=4 url: https://github.com/devluisrodrigues -timothy-jeong: - login: timothy-jeong +11kkw: + login: 11kkw count: 5 - avatarUrl: https://avatars.githubusercontent.com/u/53824764?u=db3d0cea2f5fab64d810113c5039a369699a2774&v=4 - url: https://github.com/timothy-jeong + avatarUrl: https://avatars.githubusercontent.com/u/21125286?v=4 + url: https://github.com/11kkw lpdswing: login: lpdswing count: 4 @@ -976,7 +1016,7 @@ SepehrRasouli: Zxilly: login: Zxilly 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 eavv: login: eavv @@ -1016,7 +1056,7 @@ personage-hub: aminalaee: login: aminalaee 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 erfan-rfmhr: login: erfan-rfmhr @@ -1058,11 +1098,11 @@ matiasbertani: count: 4 avatarUrl: https://avatars.githubusercontent.com/u/65260383?u=d5edd86a6e2ab4fb1aab7751931fe045a963afd7&v=4 url: https://github.com/matiasbertani -k94-ishi: - login: k94-ishi +thiennc254: + login: thiennc254 count: 4 - avatarUrl: https://avatars.githubusercontent.com/u/32672580?u=bc7c5c07af0656be9fe4f1784a444af8d81ded89&v=4 - url: https://github.com/k94-ishi + avatarUrl: https://avatars.githubusercontent.com/u/97406628?u=1b2860679694b9a552764d0fa81dbd7a016322ec&v=4 + url: https://github.com/thiennc254 javillegasna: login: javillegasna count: 4 @@ -1078,11 +1118,16 @@ ilhamfadillah: count: 4 avatarUrl: https://avatars.githubusercontent.com/u/20577838?u=c56192cf99b55affcaad408b240259c62e633450&v=4 url: https://github.com/ilhamfadillah -Yarous: - login: Yarous +gerry-sabar: + login: gerry-sabar count: 4 - avatarUrl: https://avatars.githubusercontent.com/u/61277193?u=5b462347458a373b2d599c6f416d2b75eddbffad&v=4 - url: https://github.com/Yarous + avatarUrl: https://avatars.githubusercontent.com/u/1120123?v=4 + 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: login: tyronedamasceno count: 3 @@ -1308,11 +1353,16 @@ RyaWcksn: count: 3 avatarUrl: https://avatars.githubusercontent.com/u/42831964?u=0cb4265faf3e3425a89e59b6fddd3eb2de180af0&v=4 url: https://github.com/RyaWcksn -gerry-sabar: - login: gerry-sabar +Zerohertz: + login: Zerohertz count: 3 - avatarUrl: https://avatars.githubusercontent.com/u/1120123?v=4 - url: https://github.com/gerry-sabar + avatarUrl: https://avatars.githubusercontent.com/u/42334717?u=c6acda352c866b1747921e0ff8782b58571d849e&v=4 + url: https://github.com/Zerohertz +tienduong-21: + login: tienduong-21 + count: 3 + avatarUrl: https://avatars.githubusercontent.com/u/80129618?v=4 + url: https://github.com/tienduong-21 blaisep: login: blaisep count: 2 @@ -1471,7 +1521,7 @@ felipebpl: iudeen: login: iudeen 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 dwisulfahnur: login: dwisulfahnur @@ -1623,6 +1673,16 @@ UN-9BOT: count: 2 avatarUrl: https://avatars.githubusercontent.com/u/111110804?u=39e158937ed795972c2d0400fc521c50e9bfb9e7&v=4 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: login: gustavoprezoto count: 2 @@ -1668,3 +1728,8 @@ kiharito: count: 2 avatarUrl: https://avatars.githubusercontent.com/u/38311245?v=4 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 diff --git a/docs/en/data/translators.yml b/docs/en/data/translators.yml index 13859044d..9874afa56 100644 --- a/docs/en/data/translators.yml +++ b/docs/en/data/translators.yml @@ -10,7 +10,7 @@ jaystone776: url: https://github.com/jaystone776 ceb10n: login: ceb10n - count: 26 + count: 27 avatarUrl: https://avatars.githubusercontent.com/u/235213?u=edcce471814a1eba9f0cdaa4cd0de18921a940a6&v=4 url: https://github.com/ceb10n tokusumi: @@ -43,21 +43,26 @@ hard-coders: count: 15 avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4 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: login: codingjenny count: 14 avatarUrl: https://avatars.githubusercontent.com/u/103817302?u=3a042740dc0ff58615da0d8679230966fd7693e8&v=4 url: https://github.com/codingjenny +valentinDruzhinin: + login: valentinDruzhinin + count: 14 + avatarUrl: https://avatars.githubusercontent.com/u/12831905?u=aae1ebc675c91e8fa582df4fcc4fc4128106344d&v=4 + url: https://github.com/valentinDruzhinin Xewus: login: Xewus count: 13 avatarUrl: https://avatars.githubusercontent.com/u/85196001?u=f8e2dc7e5104f109cef944af79050ea8d1b8f914&v=4 url: https://github.com/Xewus -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: login: Smlep count: 11 @@ -106,13 +111,18 @@ batlopes: lucasbalieiro: login: lucasbalieiro 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 Alexandrhub: login: Alexandrhub count: 6 avatarUrl: https://avatars.githubusercontent.com/u/119126536?u=9fc0d48f3307817bafecc5861eb2168401a6cb04&v=4 url: https://github.com/Alexandrhub +ptt3199: + login: ptt3199 + count: 6 + avatarUrl: https://avatars.githubusercontent.com/u/51350651?u=ccf51f8820787e17983954f26b06acf226cba293&v=4 + url: https://github.com/ptt3199 Serrones: login: Serrones count: 5 @@ -143,6 +153,11 @@ rostik1410: count: 5 avatarUrl: https://avatars.githubusercontent.com/u/11443899?u=e26a635c2ba220467b308a326a579b8ccf4a8701&v=4 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: login: komtaki count: 4 @@ -188,11 +203,6 @@ kwang1215: count: 4 avatarUrl: https://avatars.githubusercontent.com/u/74170199?u=2a63ff6692119dde3f5e5693365b9fcd6f977b08&v=4 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: login: jfunez count: 3 @@ -201,7 +211,7 @@ jfunez: ycd: login: ycd 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 mariacamilagl: login: mariacamilagl @@ -323,6 +333,16 @@ gerry-sabar: count: 3 avatarUrl: https://avatars.githubusercontent.com/u/1120123?v=4 url: https://github.com/gerry-sabar +k94-ishi: + login: k94-ishi + count: 3 + avatarUrl: https://avatars.githubusercontent.com/u/32672580?u=bc7c5c07af0656be9fe4f1784a444af8d81ded89&v=4 + url: https://github.com/k94-ishi +Rishat-F: + login: Rishat-F + count: 3 + avatarUrl: https://avatars.githubusercontent.com/u/66554797?v=4 + url: https://github.com/Rishat-F izaguerreiro: login: izaguerreiro count: 2 @@ -451,7 +471,7 @@ choi-haram: imtiaz101325: login: imtiaz101325 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 waketzheng: login: waketzheng @@ -488,8 +508,8 @@ timothy-jeong: count: 2 avatarUrl: https://avatars.githubusercontent.com/u/53824764?u=db3d0cea2f5fab64d810113c5039a369699a2774&v=4 url: https://github.com/timothy-jeong -Rishat-F: - login: Rishat-F +11kkw: + login: 11kkw count: 2 - avatarUrl: https://avatars.githubusercontent.com/u/66554797?v=4 - url: https://github.com/Rishat-F + avatarUrl: https://avatars.githubusercontent.com/u/21125286?v=4 + url: https://github.com/11kkw From ea57612d69290be8298369d9f1542d6afeea459e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sat, 1 Mar 2025 18:19:34 +0100 Subject: [PATCH 03/22] =?UTF-8?q?=F0=9F=91=A5=20Update=20FastAPI=20GitHub?= =?UTF-8?q?=20topic=20repositories=20(#13439)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: github-actions --- docs/en/data/topic_repos.yml | 336 +++++++++++++++++------------------ 1 file changed, 168 insertions(+), 168 deletions(-) diff --git a/docs/en/data/topic_repos.yml b/docs/en/data/topic_repos.yml index 302dc3bb5..633b0aee3 100644 --- a/docs/en/data/topic_repos.yml +++ b/docs/en/data/topic_repos.yml @@ -1,86 +1,86 @@ - name: full-stack-fastapi-template html_url: https://github.com/fastapi/full-stack-fastapi-template - stars: 29409 + stars: 30645 owner_login: fastapi owner_html_url: https://github.com/fastapi - name: Hello-Python html_url: https://github.com/mouredev/Hello-Python - stars: 28113 + stars: 28690 owner_login: mouredev owner_html_url: https://github.com/mouredev - name: serve html_url: https://github.com/jina-ai/serve - stars: 21264 + stars: 21356 owner_login: jina-ai owner_html_url: https://github.com/jina-ai - name: sqlmodel html_url: https://github.com/fastapi/sqlmodel - stars: 15109 + stars: 15312 owner_login: fastapi owner_html_url: https://github.com/fastapi - name: HivisionIDPhotos html_url: https://github.com/Zeyi-Lin/HivisionIDPhotos - stars: 14564 + stars: 14957 owner_login: Zeyi-Lin owner_html_url: https://github.com/Zeyi-Lin - name: Douyin_TikTok_Download_API html_url: https://github.com/Evil0ctal/Douyin_TikTok_Download_API - stars: 10701 + stars: 11192 owner_login: Evil0ctal owner_html_url: https://github.com/Evil0ctal - name: fastapi-best-practices html_url: https://github.com/zhanymkanov/fastapi-best-practices - stars: 10180 + stars: 10501 owner_login: zhanymkanov owner_html_url: https://github.com/zhanymkanov - name: awesome-fastapi html_url: https://github.com/mjhea0/awesome-fastapi - stars: 9061 + stars: 9193 owner_login: mjhea0 owner_html_url: https://github.com/mjhea0 - name: FastUI html_url: https://github.com/pydantic/FastUI - stars: 8644 + stars: 8721 owner_login: pydantic owner_html_url: https://github.com/pydantic - name: nonebot2 html_url: https://github.com/nonebot/nonebot2 - stars: 6312 + stars: 6433 owner_login: nonebot owner_html_url: https://github.com/nonebot - name: serge html_url: https://github.com/serge-chat/serge - stars: 5686 + stars: 5699 owner_login: serge-chat owner_html_url: https://github.com/serge-chat - name: FileCodeBox html_url: https://github.com/vastsa/FileCodeBox - stars: 4933 + stars: 5534 owner_login: vastsa owner_html_url: https://github.com/vastsa - name: fastapi-users html_url: https://github.com/fastapi-users/fastapi-users - stars: 4849 + stars: 4921 owner_login: 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 html_url: https://github.com/hatchet-dev/hatchet - stars: 4514 + stars: 4585 owner_login: hatchet-dev owner_html_url: https://github.com/hatchet-dev - name: chatgpt-web-share html_url: https://github.com/chatpire/chatgpt-web-share - stars: 4319 + stars: 4318 owner_login: 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 html_url: https://github.com/strawberry-graphql/strawberry - stars: 4126 + stars: 4180 owner_login: strawberry-graphql owner_html_url: https://github.com/strawberry-graphql - name: atrilabs-engine @@ -90,279 +90,284 @@ owner_html_url: https://github.com/Atri-Labs - name: dynaconf html_url: https://github.com/dynaconf/dynaconf - stars: 3874 + stars: 3904 owner_login: dynaconf owner_html_url: https://github.com/dynaconf - name: poem html_url: https://github.com/poem-web/poem - stars: 3746 + stars: 3781 owner_login: 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 html_url: https://github.com/rashadphz/farfalle - stars: 3094 + stars: 3190 owner_login: rashadphz owner_html_url: https://github.com/rashadphz +- name: opyrator + html_url: https://github.com/ml-tooling/opyrator + stars: 3119 + owner_login: ml-tooling + owner_html_url: https://github.com/ml-tooling - name: fastapi-admin html_url: https://github.com/fastapi-admin/fastapi-admin - stars: 3040 + stars: 3086 owner_login: fastapi-admin owner_html_url: https://github.com/fastapi-admin - name: docarray html_url: https://github.com/docarray/docarray - stars: 3007 + stars: 3021 owner_login: docarray owner_html_url: https://github.com/docarray - name: datamodel-code-generator html_url: https://github.com/koxudaxi/datamodel-code-generator - stars: 2914 + stars: 2988 owner_login: 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 html_url: https://github.com/Lightning-AI/LitServe - stars: 2804 + stars: 2863 owner_login: Lightning-AI owner_html_url: https://github.com/Lightning-AI -- name: uvicorn-gunicorn-fastapi-docker - html_url: https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker - stars: 2730 - owner_login: tiangolo - owner_html_url: https://github.com/tiangolo +- name: fastapi-realworld-example-app + html_url: https://github.com/nsidnev/fastapi-realworld-example-app + stars: 2850 + owner_login: nsidnev + owner_html_url: https://github.com/nsidnev - name: logfire html_url: https://github.com/pydantic/logfire - stars: 2620 + stars: 2757 owner_login: pydantic owner_html_url: https://github.com/pydantic +- name: uvicorn-gunicorn-fastapi-docker + html_url: https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker + stars: 2731 + owner_login: tiangolo + owner_html_url: https://github.com/tiangolo - name: huma html_url: https://github.com/danielgtaylor/huma - stars: 2567 + stars: 2700 owner_login: danielgtaylor owner_html_url: https://github.com/danielgtaylor - name: tracecat html_url: https://github.com/TracecatHQ/tracecat - stars: 2494 + stars: 2539 owner_login: TracecatHQ owner_html_url: https://github.com/TracecatHQ - name: best-of-web-python html_url: https://github.com/ml-tooling/best-of-web-python - stars: 2433 + stars: 2460 owner_login: ml-tooling owner_html_url: https://github.com/ml-tooling - name: RasaGPT html_url: https://github.com/paulpierre/RasaGPT - stars: 2386 + stars: 2401 owner_login: paulpierre owner_html_url: https://github.com/paulpierre - name: fastapi-react html_url: https://github.com/Buuntu/fastapi-react - stars: 2293 + stars: 2315 owner_login: Buuntu owner_html_url: https://github.com/Buuntu - name: nextpy html_url: https://github.com/dot-agent/nextpy - stars: 2256 + stars: 2266 owner_login: dot-agent owner_html_url: https://github.com/dot-agent - name: 30-Days-of-Python html_url: https://github.com/codingforentrepreneurs/30-Days-of-Python - stars: 2155 + stars: 2163 owner_login: codingforentrepreneurs owner_html_url: https://github.com/codingforentrepreneurs - name: FastAPI-template html_url: https://github.com/s3rius/FastAPI-template - stars: 2121 + stars: 2156 owner_login: s3rius owner_html_url: https://github.com/s3rius - name: sqladmin html_url: https://github.com/aminalaee/sqladmin - stars: 2021 + stars: 2051 owner_login: aminalaee owner_html_url: https://github.com/aminalaee - name: langserve html_url: https://github.com/langchain-ai/langserve - stars: 2006 + stars: 2025 owner_login: langchain-ai owner_html_url: https://github.com/langchain-ai - name: fastapi-utils html_url: https://github.com/fastapiutils/fastapi-utils - stars: 2002 + stars: 2021 owner_login: fastapiutils owner_html_url: https://github.com/fastapiutils - name: solara html_url: https://github.com/widgetti/solara - stars: 1967 + stars: 1980 owner_login: widgetti owner_html_url: https://github.com/widgetti - name: supabase-py html_url: https://github.com/supabase/supabase-py - stars: 1848 + stars: 1874 owner_login: supabase owner_html_url: https://github.com/supabase - name: python-week-2022 html_url: https://github.com/rochacbruno/python-week-2022 - stars: 1832 + stars: 1829 owner_login: rochacbruno owner_html_url: https://github.com/rochacbruno - name: mangum html_url: https://github.com/Kludex/mangum - stars: 1789 + stars: 1820 owner_login: Kludex owner_html_url: https://github.com/Kludex +- name: Kokoro-FastAPI + html_url: https://github.com/remsky/Kokoro-FastAPI + stars: 1771 + owner_login: remsky + owner_html_url: https://github.com/remsky - name: manage-fastapi html_url: https://github.com/ycd/manage-fastapi - stars: 1711 + stars: 1719 owner_login: ycd owner_html_url: https://github.com/ycd - name: ormar html_url: https://github.com/collerek/ormar - stars: 1701 + stars: 1710 owner_login: collerek owner_html_url: https://github.com/collerek - name: agentkit html_url: https://github.com/BCG-X-Official/agentkit - stars: 1630 + stars: 1658 owner_login: BCG-X-Official owner_html_url: https://github.com/BCG-X-Official - name: langchain-serve html_url: https://github.com/jina-ai/langchain-serve - stars: 1617 + stars: 1618 owner_login: jina-ai owner_html_url: https://github.com/jina-ai - name: termpair html_url: https://github.com/cs01/termpair - stars: 1612 + stars: 1611 owner_login: cs01 owner_html_url: https://github.com/cs01 - name: coronavirus-tracker-api html_url: https://github.com/ExpDev07/coronavirus-tracker-api - stars: 1590 + stars: 1588 owner_login: ExpDev07 owner_html_url: https://github.com/ExpDev07 - name: piccolo html_url: https://github.com/piccolo-orm/piccolo - stars: 1519 + stars: 1546 owner_login: 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 html_url: https://github.com/long2ice/fastapi-cache - stars: 1447 + stars: 1478 owner_login: long2ice owner_html_url: https://github.com/long2ice - name: openapi-python-client html_url: https://github.com/openapi-generators/openapi-python-client - stars: 1434 + stars: 1467 owner_login: openapi-generators owner_html_url: https://github.com/openapi-generators +- name: fastapi-crudrouter + html_url: https://github.com/awtkns/fastapi-crudrouter + stars: 1462 + owner_login: awtkns + owner_html_url: https://github.com/awtkns - name: awesome-fastapi-projects html_url: https://github.com/Kludex/awesome-fastapi-projects - stars: 1398 + stars: 1418 owner_login: Kludex owner_html_url: https://github.com/Kludex - name: awesome-python-resources html_url: https://github.com/DjangoEx/awesome-python-resources - stars: 1380 + stars: 1383 owner_login: 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 html_url: https://github.com/ebhy/budgetml stars: 1344 owner_login: 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 html_url: https://github.com/uriyyo/fastapi-pagination - stars: 1263 + stars: 1284 owner_login: uriyyo owner_html_url: https://github.com/uriyyo - name: fastapi-boilerplate html_url: https://github.com/teamhide/fastapi-boilerplate - stars: 1206 + stars: 1234 owner_login: teamhide owner_html_url: https://github.com/teamhide - name: fastapi-tutorial html_url: https://github.com/liaogx/fastapi-tutorial - stars: 1178 + stars: 1181 owner_login: liaogx owner_html_url: https://github.com/liaogx - name: fastapi-amis-admin html_url: https://github.com/amisadmin/fastapi-amis-admin - stars: 1142 + stars: 1164 owner_login: amisadmin owner_html_url: https://github.com/amisadmin - name: fastapi-code-generator html_url: https://github.com/koxudaxi/fastapi-code-generator - stars: 1119 + stars: 1132 owner_login: koxudaxi owner_html_url: https://github.com/koxudaxi - name: bolt-python html_url: https://github.com/slackapi/bolt-python - stars: 1116 + stars: 1130 owner_login: 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 html_url: https://github.com/langchain-ai/langchain-extract - stars: 1093 + stars: 1110 owner_login: langchain-ai owner_html_url: https://github.com/langchain-ai +- name: odmantic + html_url: https://github.com/art049/odmantic + stars: 1104 + owner_login: art049 + owner_html_url: https://github.com/art049 - name: fastapi_production_template html_url: https://github.com/zhanymkanov/fastapi_production_template - stars: 1078 + stars: 1093 owner_login: zhanymkanov owner_html_url: https://github.com/zhanymkanov +- name: SurfSense + html_url: https://github.com/MODSetter/SurfSense + stars: 1081 + owner_login: MODSetter + owner_html_url: https://github.com/MODSetter - name: fastapi-alembic-sqlmodel-async html_url: https://github.com/jonra1993/fastapi-alembic-sqlmodel-async - stars: 1055 + stars: 1063 owner_login: 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 html_url: https://github.com/trallnag/prometheus-fastapi-instrumentator - stars: 1036 + stars: 1059 owner_login: 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 html_url: https://github.com/aws-samples/bedrock-claude-chat - stars: 1010 + stars: 1039 owner_login: aws-samples owner_html_url: https://github.com/aws-samples - name: runhouse html_url: https://github.com/run-house/runhouse - stars: 1000 + stars: 1005 owner_login: run-house owner_html_url: https://github.com/run-house +- name: vue-fastapi-admin + html_url: https://github.com/mizhexiaoxiao/vue-fastapi-admin + stars: 987 + owner_login: mizhexiaoxiao + owner_html_url: https://github.com/mizhexiaoxiao - name: lanarky html_url: https://github.com/ajndkr/lanarky stars: 986 @@ -370,126 +375,121 @@ owner_html_url: https://github.com/ajndkr - name: autollm html_url: https://github.com/viddexa/autollm - stars: 982 + stars: 986 owner_login: viddexa owner_html_url: https://github.com/viddexa - name: restish html_url: https://github.com/danielgtaylor/restish - stars: 970 + stars: 984 owner_login: danielgtaylor owner_html_url: https://github.com/danielgtaylor - name: fastcrud html_url: https://github.com/igorbenav/fastcrud - stars: 929 + stars: 964 owner_login: igorbenav owner_html_url: https://github.com/igorbenav - name: secure html_url: https://github.com/TypeError/secure - stars: 921 + stars: 928 owner_login: TypeError owner_html_url: https://github.com/TypeError - name: langcorn html_url: https://github.com/msoedov/langcorn - stars: 915 + stars: 916 owner_login: 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 html_url: https://github.com/iusztinpaul/energy-forecasting - stars: 891 + stars: 898 owner_login: iusztinpaul owner_html_url: https://github.com/iusztinpaul - name: authx html_url: https://github.com/yezz123/authx - stars: 862 + stars: 874 owner_login: yezz123 owner_html_url: https://github.com/yezz123 - name: titiler html_url: https://github.com/developmentseed/titiler - stars: 823 + stars: 841 owner_login: 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 html_url: https://github.com/igorbenav/FastAPI-boilerplate - stars: 774 + stars: 820 owner_login: 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 html_url: https://github.com/fastapi-practices/fastapi_best_architecture - stars: 766 + stars: 802 owner_login: 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 html_url: https://github.com/dunossauro/fastapi-do-zero - stars: 723 + stars: 745 owner_login: dunossauro owner_html_url: https://github.com/dunossauro -- name: lccn_predictor - html_url: https://github.com/baoliay2008/lccn_predictor - stars: 718 - owner_login: baoliay2008 - owner_html_url: https://github.com/baoliay2008 +- name: fastapi-mail + html_url: https://github.com/sabuhish/fastapi-mail + stars: 744 + owner_login: sabuhish + owner_html_url: https://github.com/sabuhish - name: fastapi-observability html_url: https://github.com/blueswen/fastapi-observability - stars: 718 + stars: 743 owner_login: blueswen owner_html_url: https://github.com/blueswen -- name: chatGPT-web - html_url: https://github.com/mic1on/chatGPT-web - stars: 708 - owner_login: mic1on - owner_html_url: https://github.com/mic1on +- name: lccn_predictor + html_url: https://github.com/baoliay2008/lccn_predictor + stars: 741 + owner_login: baoliay2008 + owner_html_url: https://github.com/baoliay2008 +- name: annotated-py-projects + html_url: https://github.com/hhstore/annotated-py-projects + stars: 727 + owner_login: hhstore + owner_html_url: https://github.com/hhstore - name: learn-generative-ai html_url: https://github.com/panaverse/learn-generative-ai - stars: 701 + stars: 714 owner_login: 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 html_url: https://github.com/jowilf/starlette-admin - stars: 692 + stars: 713 owner_login: 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 html_url: https://github.com/IndominusByte/fastapi-jwt-auth - stars: 674 + stars: 685 owner_login: IndominusByte owner_html_url: https://github.com/IndominusByte - name: pity html_url: https://github.com/wuranxu/pity - stars: 663 + stars: 667 owner_login: 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 From b7d3f2a96ec2e3d548a1cbd8046dbfecdee38acf Mon Sep 17 00:00:00 2001 From: github-actions Date: Sat, 1 Mar 2025 17:19:45 +0000 Subject: [PATCH 04/22] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index f78994c5a..6ac228ba1 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -11,6 +11,10 @@ hide: * 🌐 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 People - Sponsors. PR [#13433](https://github.com/fastapi/fastapi/pull/13433) by [@tiangolo](https://github.com/tiangolo). + ## 0.115.10 ### Fixes From 60f05868b786337cf00504fd5e5df2a46c6cd6d3 Mon Sep 17 00:00:00 2001 From: github-actions Date: Sat, 1 Mar 2025 17:20:07 +0000 Subject: [PATCH 05/22] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 6ac228ba1..37cb9aa56 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### Internal +* πŸ‘₯ 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 From f5056f84b66344ee4fc0e15eff763cdb35381b5c Mon Sep 17 00:00:00 2001 From: github-actions Date: Sat, 1 Mar 2025 17:21:19 +0000 Subject: [PATCH 06/22] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 37cb9aa56..80075319d 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### 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). From 74fe89bf35034aae531ca0a527c37d2f545161f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sat, 1 Mar 2025 23:02:35 +0100 Subject: [PATCH 07/22] =?UTF-8?q?=F0=9F=90=9B=20Add=20docs=20examples=20an?= =?UTF-8?q?d=20tests=20(support)=20for=20`Annotated`=20custom=20validation?= =?UTF-8?q?s,=20like=20`AfterValidator`,=20revert=20#13440=20(#13442)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 15dd2b67d3f8763d5cd523b79a1c901c05d48bd7. --- .../tutorial/query-params-str-validations.md | 64 ++++++++ .../tutorial015_an.py | 31 ++++ .../tutorial015_an_py310.py | 30 ++++ .../tutorial015_an_py39.py | 30 ++++ fastapi/dependencies/utils.py | 8 +- tests/test_analyze_param.py | 22 --- .../test_tutorial015.py | 143 ++++++++++++++++++ 7 files changed, 302 insertions(+), 26 deletions(-) create mode 100644 docs_src/query_params_str_validations/tutorial015_an.py create mode 100644 docs_src/query_params_str_validations/tutorial015_an_py310.py create mode 100644 docs_src/query_params_str_validations/tutorial015_an_py39.py delete mode 100644 tests/test_analyze_param.py create mode 100644 tests/test_tutorial/test_query_params_str_validations/test_tutorial015.py diff --git a/docs/en/docs/tutorial/query-params-str-validations.md b/docs/en/docs/tutorial/query-params-str-validations.md index 511099186..e50fc347c 100644 --- a/docs/en/docs/tutorial/query-params-str-validations.md +++ b/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] *} +## 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 Pydantic's `AfterValidator` inside of `Annotated`. + +/// tip + +Pydantic also has `BeforeValidator` and others. πŸ€“ + +/// + +For example, this custom validator checks that the item ID starts with `isbn-` for an ISBN book number or with `imdb-` for an IMDB 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 iterable object 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 You can declare additional validations and metadata for your parameters. @@ -423,6 +485,8 @@ Validations specific for strings: * `max_length` * `pattern` +Custom validations using `AfterValidator`. + 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. diff --git a/docs_src/query_params_str_validations/tutorial015_an.py b/docs_src/query_params_str_validations/tutorial015_an.py new file mode 100644 index 000000000..f2ec6db12 --- /dev/null +++ b/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} diff --git a/docs_src/query_params_str_validations/tutorial015_an_py310.py b/docs_src/query_params_str_validations/tutorial015_an_py310.py new file mode 100644 index 000000000..35f368094 --- /dev/null +++ b/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} diff --git a/docs_src/query_params_str_validations/tutorial015_an_py39.py b/docs_src/query_params_str_validations/tutorial015_an_py39.py new file mode 100644 index 000000000..989b6d2c2 --- /dev/null +++ b/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} diff --git a/fastapi/dependencies/utils.py b/fastapi/dependencies/utils.py index 09dd6f1b9..e2866b488 100644 --- a/fastapi/dependencies/utils.py +++ b/fastapi/dependencies/utils.py @@ -449,15 +449,15 @@ def analyze_param( # 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 # `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( 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): - field_info = params.Body(annotation=type_annotation, default=default_value) + field_info = params.Body(annotation=use_annotation, default=default_value) else: - field_info = params.Query(annotation=type_annotation, default=default_value) + field_info = params.Query(annotation=use_annotation, default=default_value) field = None # It's a field_info, not a dependency diff --git a/tests/test_analyze_param.py b/tests/test_analyze_param.py deleted file mode 100644 index 9fd3fa6d0..000000000 --- a/tests/test_analyze_param.py +++ /dev/null @@ -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 diff --git a/tests/test_tutorial/test_query_params_str_validations/test_tutorial015.py b/tests/test_tutorial/test_query_params_str_validations/test_tutorial015.py new file mode 100644 index 000000000..ae1c40286 --- /dev/null +++ b/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", + }, + } + }, + } + ) From a2c2e332a0936a2d6277548d612ec7a1fc957020 Mon Sep 17 00:00:00 2001 From: github-actions Date: Sat, 1 Mar 2025 22:02:59 +0000 Subject: [PATCH 08/22] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 80075319d..c4e7d051b 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,10 @@ hide: ## Latest Changes +### Fixes + +* πŸ› Add docs examples and tests (support) for `Annotated` custom validations, like `AfterValidator`, revert #13440. PR [#13442](https://github.com/fastapi/fastapi/pull/13442) by [@tiangolo](https://github.com/tiangolo). + ### 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). From a01ed2f6a71b4f5eb38cd25f4ad435b749f120df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sat, 1 Mar 2025 23:13:11 +0100 Subject: [PATCH 09/22] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index c4e7d051b..0c92d966d 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -9,7 +9,8 @@ hide: ### Fixes -* πŸ› Add docs examples and tests (support) for `Annotated` custom validations, like `AfterValidator`, revert #13440. PR [#13442](https://github.com/fastapi/fastapi/pull/13442) by [@tiangolo](https://github.com/tiangolo). +* πŸ› 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 From 3824664620433f0055125adbf2fc212ced2bdf94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Sat, 1 Mar 2025 23:14:01 +0100 Subject: [PATCH 10/22] =?UTF-8?q?=F0=9F=94=96=20Release=20version=200.115.?= =?UTF-8?q?11?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/docs/release-notes.md | 2 ++ fastapi/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 0c92d966d..0679ce8a1 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,8 @@ hide: ## Latest Changes +## 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). diff --git a/fastapi/__init__.py b/fastapi/__init__.py index a6e7e47fd..757b76106 100644 --- a/fastapi/__init__.py +++ b/fastapi/__init__.py @@ -1,6 +1,6 @@ """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 316566e40efb5b7dabc549ff0060a016e68719ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Mon, 3 Mar 2025 15:33:33 +0100 Subject: [PATCH 11/22] =?UTF-8?q?=F0=9F=94=A7=20Update=20sponsors:=20pause?= =?UTF-8?q?=20TestDriven=20(#13446)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/en/data/sponsors.yml | 6 +++--- docs/en/docs/advanced/index.md | 15 --------------- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/docs/en/data/sponsors.yml b/docs/en/data/sponsors.yml index b994e533a..5cbf05f9d 100644 --- a/docs/en/data/sponsors.yml +++ b/docs/en/data/sponsors.yml @@ -58,9 +58,9 @@ bronze: - url: https://www.exoflare.com/open-source/?utm_source=FastAPI&utm_campaign=open_source title: Biosecurity risk assessments made easy. img: https://fastapi.tiangolo.com/img/sponsors/exoflare.png - - url: https://testdriven.io/courses/tdd-fastapi/ - title: Learn to build high-quality web apps with best practices - img: https://fastapi.tiangolo.com/img/sponsors/testdriven.svg + # - url: https://testdriven.io/courses/tdd-fastapi/ + # title: Learn to build high-quality web apps with best practices + # 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 title: LambdaTest, AI-Powered Cloud-based Test Orchestration Platform img: https://fastapi.tiangolo.com/img/sponsors/lambdatest.png diff --git a/docs/en/docs/advanced/index.md b/docs/en/docs/advanced/index.md index 36f0720c0..47385e2c6 100644 --- a/docs/en/docs/advanced/index.md +++ b/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}. 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: - -* Talk Python Training -* Test-Driven Development From ab22979dc566619f72eb989aacb84c95539ae5a4 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 3 Mar 2025 14:33:58 +0000 Subject: [PATCH 12/22] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 0679ce8a1..72c47d4fb 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,10 @@ hide: ## Latest Changes +### Internal + +* πŸ”§ Update sponsors: pause TestDriven. PR [#13446](https://github.com/fastapi/fastapi/pull/13446) by [@tiangolo](https://github.com/tiangolo). + ## 0.115.11 ### Fixes From 8c94e97c89f617ad808d8ca24da6e52a238bcee9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Mar 2025 13:18:57 +0100 Subject: [PATCH 13/22] =?UTF-8?q?=E2=AC=86=20Bump=20ruff=20to=200.9.4=20(#?= =?UTF-8?q?13299)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ⬆ Bump ruff from 0.6.4 to 0.9.4 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.6.4 to 0.9.4. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.6.4...0.9.4) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * update pre-commit accordingly and make formatting changes * 🎨 [pre-commit.ci] Auto format from pre-commit.com hooks --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Alejandra <90076947+alejsdev@users.noreply.github.com> Co-authored-by: svlandeg Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- fastapi/dependencies/utils.py | 42 +++++++-------- fastapi/openapi/utils.py | 12 ++--- fastapi/routing.py | 24 ++++----- requirements-docs-tests.txt | 2 +- scripts/translate.py | 12 ++--- tests/test_enforce_once_required_parameter.py | 6 +-- tests/test_generic_parameterless_depends.py | 4 +- tests/test_repeated_dependency_schema.py | 6 +-- .../test_tutorial001.py | 48 ++++++++--------- .../test_tutorial002.py | 54 +++++++++---------- .../test_tutorial003.py | 54 +++++++++---------- .../test_sql_databases/test_tutorial002.py | 6 +-- 13 files changed, 136 insertions(+), 136 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 767ef8d9e..05c33a608 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.7.4 + rev: v0.9.4 hooks: - id: ruff args: diff --git a/fastapi/dependencies/utils.py b/fastapi/dependencies/utils.py index e2866b488..d205d17fa 100644 --- a/fastapi/dependencies/utils.py +++ b/fastapi/dependencies/utils.py @@ -133,9 +133,9 @@ def get_param_sub_dependant( def get_parameterless_sub_dependant(*, depends: params.Depends, path: str) -> Dependant: - assert callable( - depends.dependency - ), "A parameter-less dependency must have a callable dependency" + assert callable(depends.dependency), ( + "A parameter-less dependency must have a callable dependency" + ) return get_sub_dependant(depends=depends, dependency=depends.dependency, path=path) @@ -302,9 +302,9 @@ def get_dependant( type_annotation=param_details.type_annotation, dependant=dependant, ): - assert ( - param_details.field is None - ), f"Cannot specify multiple FastAPI annotations for {param_name!r}" + assert param_details.field is None, ( + f"Cannot specify multiple FastAPI annotations for {param_name!r}" + ) continue assert param_details.field is not None 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 ( - field_info is None - ), f"Cannot specify FastAPI annotation for type {type_annotation!r}" + assert field_info is None, ( + 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 elif field_info is None and depends is None: default_value = value if value is not inspect.Signature.empty else RequiredParam @@ -494,9 +494,9 @@ def analyze_param( field_info=field_info, ) if is_path_param: - assert is_scalar_field( - field=field - ), "Path params must be of one of the supported types" + assert is_scalar_field(field=field), ( + "Path params must be of one of the supported types" + ) elif isinstance(field_info, params.Query): assert ( 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: dependant.header_params.append(field) else: - assert ( - field_info_in == params.ParamTypes.cookie - ), f"non-body parameters must be in path, query, header or cookie: {field.name}" + assert field_info_in == params.ParamTypes.cookie, ( + f"non-body parameters must be in path, query, header or cookie: {field.name}" + ) dependant.cookie_params.append(field) @@ -782,9 +782,9 @@ def request_params_to_args( if single_not_embedded_field: field_info = first_field.field_info - assert isinstance( - field_info, params.Param - ), "Params must be subclasses of Param" + assert isinstance(field_info, params.Param), ( + "Params must be subclasses of Param" + ) loc: Tuple[str, ...] = (field_info.in_.value,) v_, errors_ = _validate_value_with_model_field( field=first_field, value=params_to_process, values=values, loc=loc @@ -794,9 +794,9 @@ def request_params_to_args( for field in fields: value = _get_multidict_value(field, received_params) field_info = field.field_info - assert isinstance( - field_info, params.Param - ), "Params must be subclasses of Param" + assert isinstance(field_info, params.Param), ( + "Params must be subclasses of Param" + ) loc = (field_info.in_.value, field.alias) v_, errors_ = _validate_value_with_model_field( field=field, value=value, values=values, loc=loc diff --git a/fastapi/openapi/utils.py b/fastapi/openapi/utils.py index 947eca948..bd8f3c106 100644 --- a/fastapi/openapi/utils.py +++ b/fastapi/openapi/utils.py @@ -364,9 +364,9 @@ def get_openapi_path( openapi_response = operation_responses.setdefault( status_code_key, {} ) - assert isinstance( - process_response, dict - ), "An additional response must be a dict" + assert isinstance(process_response, dict), ( + "An additional response must be a dict" + ) field = route.response_fields.get(additional_status_code) additional_field_schema: Optional[Dict[str, Any]] = None if field: @@ -434,9 +434,9 @@ def get_fields_from_routes( route, routing.APIRoute ): if route.body_field: - assert isinstance( - route.body_field, ModelField - ), "A request body must be a Pydantic Field" + assert isinstance(route.body_field, ModelField), ( + "A request body must be a Pydantic Field" + ) body_fields_from_routes.append(route.body_field) if route.response_field: responses_from_routes.append(route.response_field) diff --git a/fastapi/routing.py b/fastapi/routing.py index 8ea4bb219..457481e32 100644 --- a/fastapi/routing.py +++ b/fastapi/routing.py @@ -504,9 +504,9 @@ class APIRoute(routing.Route): status_code = int(status_code) self.status_code = status_code if self.response_model: - assert is_body_allowed_for_status_code( - status_code - ), f"Status code {status_code} must not have a response body" + assert is_body_allowed_for_status_code(status_code), ( + f"Status code {status_code} must not have a response body" + ) response_name = "Response_" + self.unique_id self.response_field = create_model_field( name=response_name, @@ -537,9 +537,9 @@ class APIRoute(routing.Route): assert isinstance(response, dict), "An additional response must be a dict" model = response.get("model") if model: - assert is_body_allowed_for_status_code( - additional_status_code - ), f"Status code {additional_status_code} must not have a response body" + assert is_body_allowed_for_status_code(additional_status_code), ( + f"Status code {additional_status_code} must not have a response body" + ) response_name = f"Response_{additional_status_code}_{self.unique_id}" response_field = create_model_field( name=response_name, type_=model, mode="serialization" @@ -844,9 +844,9 @@ class APIRouter(routing.Router): ) if prefix: assert prefix.startswith("/"), "A path prefix must start with '/'" - assert not prefix.endswith( - "/" - ), "A path prefix must not end with '/', as the routes will start with '/'" + assert not prefix.endswith("/"), ( + "A path prefix must not end with '/', as the routes will start with '/'" + ) self.prefix = prefix self.tags: List[Union[str, Enum]] = tags or [] self.dependencies = list(dependencies or []) @@ -1256,9 +1256,9 @@ class APIRouter(routing.Router): """ if prefix: assert prefix.startswith("/"), "A path prefix must start with '/'" - assert not prefix.endswith( - "/" - ), "A path prefix must not end with '/', as the routes will start with '/'" + assert not prefix.endswith("/"), ( + "A path prefix must not end with '/', as the routes will start with '/'" + ) else: for r in router.routes: path = getattr(r, "path") # noqa: B009 diff --git a/requirements-docs-tests.txt b/requirements-docs-tests.txt index 331d2a5b3..e7718e61d 100644 --- a/requirements-docs-tests.txt +++ b/requirements-docs-tests.txt @@ -1,4 +1,4 @@ # For mkdocstrings and tests httpx >=0.23.0,<0.28.0 # For linting and generating docs versions -ruff ==0.6.4 +ruff ==0.9.4 diff --git a/scripts/translate.py b/scripts/translate.py index ce11b3877..9a2136d1b 100644 --- a/scripts/translate.py +++ b/scripts/translate.py @@ -38,9 +38,9 @@ def get_langs() -> dict[str, str]: def generate_lang_path(*, lang: str, path: Path) -> Path: en_docs_path = Path("docs/en/docs") - assert str(path).startswith( - str(en_docs_path) - ), f"Path must be inside {en_docs_path}" + assert str(path).startswith(str(en_docs_path)), ( + f"Path must be inside {en_docs_path}" + ) lang_docs_path = Path(f"docs/{lang}/docs") out_path = Path(str(path).replace(str(en_docs_path), str(lang_docs_path))) return out_path @@ -56,9 +56,9 @@ def translate_page(*, lang: str, path: Path) -> None: lang_prompt_content = lang_prompt_path.read_text() en_docs_path = Path("docs/en/docs") - assert str(path).startswith( - str(en_docs_path) - ), f"Path must be inside {en_docs_path}" + assert str(path).startswith(str(en_docs_path)), ( + f"Path must be inside {en_docs_path}" + ) out_path = generate_lang_path(lang=lang, path=path) out_path.parent.mkdir(parents=True, exist_ok=True) original_content = path.read_text() diff --git a/tests/test_enforce_once_required_parameter.py b/tests/test_enforce_once_required_parameter.py index b64f8341b..30329282f 100644 --- a/tests/test_enforce_once_required_parameter.py +++ b/tests/test_enforce_once_required_parameter.py @@ -48,7 +48,7 @@ expected_schema = { "type": "array", }, "msg": {"title": "Message", "type": "string"}, - "type": {"title": "Error " "Type", "type": "string"}, + "type": {"title": "Error Type", "type": "string"}, }, "required": ["loc", "msg", "type"], "title": "ValidationError", @@ -73,7 +73,7 @@ expected_schema = { "responses": { "200": { "content": {"application/json": {"schema": {}}}, - "description": "Successful " "Response", + "description": "Successful Response", }, "422": { "content": { @@ -83,7 +83,7 @@ expected_schema = { } } }, - "description": "Validation " "Error", + "description": "Validation Error", }, }, "summary": "Foo Handler", diff --git a/tests/test_generic_parameterless_depends.py b/tests/test_generic_parameterless_depends.py index fe13ff89b..5aa35320c 100644 --- a/tests/test_generic_parameterless_depends.py +++ b/tests/test_generic_parameterless_depends.py @@ -55,7 +55,7 @@ def test_openapi_schema(): "responses": { "200": { "content": {"application/json": {"schema": {}}}, - "description": "Successful " "Response", + "description": "Successful Response", } }, "summary": "A", @@ -67,7 +67,7 @@ def test_openapi_schema(): "responses": { "200": { "content": {"application/json": {"schema": {}}}, - "description": "Successful " "Response", + "description": "Successful Response", } }, "summary": "B", diff --git a/tests/test_repeated_dependency_schema.py b/tests/test_repeated_dependency_schema.py index d7d0dfa05..c21829bd9 100644 --- a/tests/test_repeated_dependency_schema.py +++ b/tests/test_repeated_dependency_schema.py @@ -41,7 +41,7 @@ schema = { "type": "array", }, "msg": {"title": "Message", "type": "string"}, - "type": {"title": "Error " "Type", "type": "string"}, + "type": {"title": "Error Type", "type": "string"}, }, "required": ["loc", "msg", "type"], "title": "ValidationError", @@ -66,7 +66,7 @@ schema = { "responses": { "200": { "content": {"application/json": {"schema": {}}}, - "description": "Successful " "Response", + "description": "Successful Response", }, "422": { "content": { @@ -76,7 +76,7 @@ schema = { } } }, - "description": "Validation " "Error", + "description": "Validation Error", }, }, "summary": "Get Deps", diff --git a/tests/test_tutorial/test_configure_swagger_ui/test_tutorial001.py b/tests/test_tutorial/test_configure_swagger_ui/test_tutorial001.py index 72db54bd2..a04dba219 100644 --- a/tests/test_tutorial/test_configure_swagger_ui/test_tutorial001.py +++ b/tests/test_tutorial/test_configure_swagger_ui/test_tutorial001.py @@ -8,31 +8,31 @@ client = TestClient(app) def test_swagger_ui(): response = client.get("/docs") assert response.status_code == 200, response.text - assert ( - '"syntaxHighlight": false' in response.text - ), "syntaxHighlight should be included and converted to JSON" - assert ( - '"dom_id": "#swagger-ui"' in response.text - ), "default configs should be preserved" + assert '"syntaxHighlight": false' in response.text, ( + "syntaxHighlight should be included and converted to JSON" + ) + assert '"dom_id": "#swagger-ui"' in response.text, ( + "default configs should be preserved" + ) assert "presets: [" in response.text, "default configs should be preserved" - assert ( - "SwaggerUIBundle.presets.apis," in response.text - ), "default configs should be preserved" - assert ( - "SwaggerUIBundle.SwaggerUIStandalonePreset" in response.text - ), "default configs should be preserved" - assert ( - '"layout": "BaseLayout",' in response.text - ), "default configs should be preserved" - assert ( - '"deepLinking": true,' in response.text - ), "default configs should be preserved" - assert ( - '"showExtensions": true,' in response.text - ), "default configs should be preserved" - assert ( - '"showCommonExtensions": true,' in response.text - ), "default configs should be preserved" + assert "SwaggerUIBundle.presets.apis," in response.text, ( + "default configs should be preserved" + ) + assert "SwaggerUIBundle.SwaggerUIStandalonePreset" in response.text, ( + "default configs should be preserved" + ) + assert '"layout": "BaseLayout",' in response.text, ( + "default configs should be preserved" + ) + assert '"deepLinking": true,' in response.text, ( + "default configs should be preserved" + ) + assert '"showExtensions": true,' in response.text, ( + "default configs should be preserved" + ) + assert '"showCommonExtensions": true,' in response.text, ( + "default configs should be preserved" + ) def test_get_users(): diff --git a/tests/test_tutorial/test_configure_swagger_ui/test_tutorial002.py b/tests/test_tutorial/test_configure_swagger_ui/test_tutorial002.py index d06a385b5..ea56b6f21 100644 --- a/tests/test_tutorial/test_configure_swagger_ui/test_tutorial002.py +++ b/tests/test_tutorial/test_configure_swagger_ui/test_tutorial002.py @@ -8,34 +8,34 @@ client = TestClient(app) def test_swagger_ui(): response = client.get("/docs") assert response.status_code == 200, response.text - assert ( - '"syntaxHighlight": false' not in response.text - ), "not used parameters should not be included" - assert ( - '"syntaxHighlight": {"theme": "obsidian"}' in response.text - ), "parameters with middle dots should be included in a JSON compatible way" - assert ( - '"dom_id": "#swagger-ui"' in response.text - ), "default configs should be preserved" + assert '"syntaxHighlight": false' not in response.text, ( + "not used parameters should not be included" + ) + assert '"syntaxHighlight": {"theme": "obsidian"}' in response.text, ( + "parameters with middle dots should be included in a JSON compatible way" + ) + assert '"dom_id": "#swagger-ui"' in response.text, ( + "default configs should be preserved" + ) assert "presets: [" in response.text, "default configs should be preserved" - assert ( - "SwaggerUIBundle.presets.apis," in response.text - ), "default configs should be preserved" - assert ( - "SwaggerUIBundle.SwaggerUIStandalonePreset" in response.text - ), "default configs should be preserved" - assert ( - '"layout": "BaseLayout",' in response.text - ), "default configs should be preserved" - assert ( - '"deepLinking": true,' in response.text - ), "default configs should be preserved" - assert ( - '"showExtensions": true,' in response.text - ), "default configs should be preserved" - assert ( - '"showCommonExtensions": true,' in response.text - ), "default configs should be preserved" + assert "SwaggerUIBundle.presets.apis," in response.text, ( + "default configs should be preserved" + ) + assert "SwaggerUIBundle.SwaggerUIStandalonePreset" in response.text, ( + "default configs should be preserved" + ) + assert '"layout": "BaseLayout",' in response.text, ( + "default configs should be preserved" + ) + assert '"deepLinking": true,' in response.text, ( + "default configs should be preserved" + ) + assert '"showExtensions": true,' in response.text, ( + "default configs should be preserved" + ) + assert '"showCommonExtensions": true,' in response.text, ( + "default configs should be preserved" + ) def test_get_users(): diff --git a/tests/test_tutorial/test_configure_swagger_ui/test_tutorial003.py b/tests/test_tutorial/test_configure_swagger_ui/test_tutorial003.py index 187e89ace..926bbb14f 100644 --- a/tests/test_tutorial/test_configure_swagger_ui/test_tutorial003.py +++ b/tests/test_tutorial/test_configure_swagger_ui/test_tutorial003.py @@ -8,34 +8,34 @@ client = TestClient(app) def test_swagger_ui(): response = client.get("/docs") assert response.status_code == 200, response.text - assert ( - '"deepLinking": false,' in response.text - ), "overridden configs should be preserved" - assert ( - '"deepLinking": true' not in response.text - ), "overridden configs should not include the old value" - assert ( - '"syntaxHighlight": false' not in response.text - ), "not used parameters should not be included" - assert ( - '"dom_id": "#swagger-ui"' in response.text - ), "default configs should be preserved" + assert '"deepLinking": false,' in response.text, ( + "overridden configs should be preserved" + ) + assert '"deepLinking": true' not in response.text, ( + "overridden configs should not include the old value" + ) + assert '"syntaxHighlight": false' not in response.text, ( + "not used parameters should not be included" + ) + assert '"dom_id": "#swagger-ui"' in response.text, ( + "default configs should be preserved" + ) assert "presets: [" in response.text, "default configs should be preserved" - assert ( - "SwaggerUIBundle.presets.apis," in response.text - ), "default configs should be preserved" - assert ( - "SwaggerUIBundle.SwaggerUIStandalonePreset" in response.text - ), "default configs should be preserved" - assert ( - '"layout": "BaseLayout",' in response.text - ), "default configs should be preserved" - assert ( - '"showExtensions": true,' in response.text - ), "default configs should be preserved" - assert ( - '"showCommonExtensions": true,' in response.text - ), "default configs should be preserved" + assert "SwaggerUIBundle.presets.apis," in response.text, ( + "default configs should be preserved" + ) + assert "SwaggerUIBundle.SwaggerUIStandalonePreset" in response.text, ( + "default configs should be preserved" + ) + assert '"layout": "BaseLayout",' in response.text, ( + "default configs should be preserved" + ) + assert '"showExtensions": true,' in response.text, ( + "default configs should be preserved" + ) + assert '"showCommonExtensions": true,' in response.text, ( + "default configs should be preserved" + ) def test_get_users(): diff --git a/tests/test_tutorial/test_sql_databases/test_tutorial002.py b/tests/test_tutorial/test_sql_databases/test_tutorial002.py index 68c1966f5..79e48c1c3 100644 --- a/tests/test_tutorial/test_sql_databases/test_tutorial002.py +++ b/tests/test_tutorial/test_sql_databases/test_tutorial002.py @@ -71,9 +71,9 @@ def test_crud_app(client: TestClient): assert response.json() == snapshot( {"age": 30, "id": IsInt(), "name": "Dead Pond"} ) - assert ( - response.json()["id"] != 9000 - ), "The ID should be generated by the database" + assert response.json()["id"] != 9000, ( + "The ID should be generated by the database" + ) # Read a hero hero_id = response.json()["id"] From daf6820307816571433824617f69f9ac51621193 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 6 Mar 2025 12:19:24 +0000 Subject: [PATCH 14/22] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 72c47d4fb..52edd7773 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -9,6 +9,7 @@ hide: ### Internal +* ⬆ 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 From a592e8ad4dba1941a3619bd270ccb0f026ec5ba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ph=C6=B0=C6=A1ng=20T=E1=BA=A5n=20Th=C3=A0nh?= <51350651+ptt3199@users.noreply.github.com> Date: Fri, 7 Mar 2025 10:24:13 +0700 Subject: [PATCH 15/22] =?UTF-8?q?=F0=9F=8C=90=20Add=20Vietnamese=20transla?= =?UTF-8?q?tion=20for=20`docs/vi/docs/deployment/cloud.md`=20(#13407)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sofie Van Landeghem Co-authored-by: Dinh Van Luc <39489075+MrL8199@users.noreply.github.com> --- docs/vi/docs/deployment/cloud.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 docs/vi/docs/deployment/cloud.md diff --git a/docs/vi/docs/deployment/cloud.md b/docs/vi/docs/deployment/cloud.md new file mode 100644 index 000000000..9ab72769d --- /dev/null +++ b/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ọ: + +* Platform.sh +* Porter +* Coherence +* Render From 0c36a7ac0587c05e3f8d6b54e65565190f68e580 Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 7 Mar 2025 03:24:33 +0000 Subject: [PATCH 16/22] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 52edd7773..e9bccf0fb 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -7,6 +7,10 @@ hide: ## Latest Changes +### Translations + +* 🌐 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 ruff to 0.9.4. PR [#13299](https://github.com/fastapi/fastapi/pull/13299) by [@dependabot[bot]](https://github.com/apps/dependabot). From a88a6050a6423630ac141a862742fca79333d516 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Mar 2025 04:24:42 +0100 Subject: [PATCH 17/22] =?UTF-8?q?=E2=AC=86=20Bump=20black=20from=2024.10.0?= =?UTF-8?q?=20to=2025.1.0=20(#13436)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [black](https://github.com/psf/black) from 24.10.0 to 25.1.0. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/compare/24.10.0...25.1.0) --- updated-dependencies: - dependency-name: black dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements-docs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-docs.txt b/requirements-docs.txt index cd2e4e58e..8812e27f9 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -14,6 +14,6 @@ cairosvg==2.7.1 mkdocstrings[python]==0.26.1 griffe-typingdoc==0.2.7 # For griffe, it formats with black -black==24.10.0 +black==25.1.0 mkdocs-macros-plugin==1.3.7 markdown-include-variants==0.0.4 From 79bc28fab4b33c7822a5a30408ec0fec69d6630c Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 7 Mar 2025 03:25:02 +0000 Subject: [PATCH 18/22] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index e9bccf0fb..86f9ab0cb 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### Internal +* ⬆ 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). From c46e4a1b1424cef38349627a32b4419d0a2a1612 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Mar 2025 04:25:10 +0100 Subject: [PATCH 19/22] =?UTF-8?q?=E2=AC=86=20Bump=20sqlmodel=20from=200.0.?= =?UTF-8?q?22=20to=200.0.23=20(#13437)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [sqlmodel](https://github.com/fastapi/sqlmodel) from 0.0.22 to 0.0.23. - [Release notes](https://github.com/fastapi/sqlmodel/releases) - [Changelog](https://github.com/fastapi/sqlmodel/blob/main/docs/release-notes.md) - [Commits](https://github.com/fastapi/sqlmodel/compare/0.0.22...0.0.23) --- updated-dependencies: - dependency-name: sqlmodel dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-tests.txt b/requirements-tests.txt index 4a15844e4..6a870add6 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -4,7 +4,7 @@ pytest >=7.1.3,<9.0.0 coverage[toml] >= 6.5.0,< 8.0 mypy ==1.8.0 dirty-equals ==0.8.0 -sqlmodel==0.0.22 +sqlmodel==0.0.23 flask >=1.1.2,<4.0.0 anyio[trio] >=3.2.1,<5.0.0 PyJWT==2.8.0 From 643d2845de09a437b955a163ab25eb0887bfd0e1 Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 7 Mar 2025 03:25:46 +0000 Subject: [PATCH 20/22] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 86f9ab0cb..ee987b544 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -13,6 +13,7 @@ hide: ### 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). From 3565ea00b6a3193743dddb98bdd47f878374ae64 Mon Sep 17 00:00:00 2001 From: Lee Yesong Date: Mon, 10 Mar 2025 21:29:03 +0900 Subject: [PATCH 21/22] =?UTF-8?q?=F0=9F=8C=90=20Add=20Korean=20translation?= =?UTF-8?q?=20for=20`docs/ko/docs/tutorial/security/oauth2-jwt.md`=20(#133?= =?UTF-8?q?33)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ko/docs/tutorial/security/oauth2-jwt.md | 273 +++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100644 docs/ko/docs/tutorial/security/oauth2-jwt.md diff --git a/docs/ko/docs/tutorial/security/oauth2-jwt.md b/docs/ko/docs/tutorial/security/oauth2-jwt.md new file mode 100644 index 000000000..d8bac8346 --- /dev/null +++ b/docs/ko/docs/tutorial/security/oauth2-jwt.md @@ -0,0 +1,273 @@ +# νŒ¨μŠ€μ›Œλ“œ 해싱을 μ΄μš©ν•œ OAuth2, JWT 토큰을 μ‚¬μš©ν•˜λŠ” Bearer 인증 + +λͺ¨λ“  λ³΄μ•ˆ 흐름을 κ΅¬μ„±ν–ˆμœΌλ―€λ‘œ, 이제 JWT 토큰과 νŒ¨μŠ€μ›Œλ“œ 해싱을 μ‚¬μš©ν•΄ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ•ˆμ „ν•˜κ²Œ λ§Œλ“€ κ²ƒμž…λ‹ˆλ‹€. + +이 μ½”λ“œλŠ” μ‹€μ œλ‘œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ νŒ¨μŠ€μ›Œλ“œλ₯Ό ν•΄μ‹±ν•˜μ—¬ DB에 μ €μž₯ν•˜λŠ” λ“±μ˜ μž‘μ—…μ— ν™œμš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. + +이전 μž₯에 μ΄μ–΄μ„œ μ‹œμž‘ν•΄ λ΄…μ‹œλ‹€. + +## JWT + +JWT λŠ” "JSON Web Tokens" 을 μ˜λ―Έν•©λ‹ˆλ‹€. + +JSON 객체λ₯Ό 곡백이 μ—†λŠ” κΈ΄ λ¬Έμžμ—΄λ‘œ μΈμ½”λ”©ν•˜λŠ” ν‘œμ€€μ΄λ©°, λ‹€μŒκ³Ό 같은 ν˜•νƒœμž…λ‹ˆλ‹€: + +``` +eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c +``` + +JWTλŠ” μ•”ν˜Έν™”λ˜μ§€ μ•Šμ•„ λˆ„κ΅¬λ“ μ§€ ν† ν°μ—μ„œ 정보λ₯Ό 볡원할 수 μžˆμŠ΅λ‹ˆλ‹€. + +ν•˜μ§€λ§Œ JWTλŠ” μ„œλͺ…λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. κ·Έλž˜μ„œ μžμ‹ μ΄ λ°œκΈ‰ν•œ 토큰을 λ°›μ•˜μ„ λ•Œ, μ‹€μ œλ‘œ μžμ‹ μ΄ λ°œκΈ‰ν•œκ²Œ λ§žλŠ”μ§€ 검증할 수 μžˆμŠ΅λ‹ˆλ‹€. + +만료 기간이 일주일인 토큰을 λ°œν–‰ν–ˆλ‹€κ³  κ°€μ •ν•΄ λ΄…μ‹œλ‹€. λ‹€μŒ λ‚  μ‚¬μš©μžκ°€ 토큰을 가져왔을 λ•Œ, κ·Έ μ‚¬μš©μžκ°€ μ‹œμŠ€ν…œμ— μ—¬μ „νžˆ λ‘œκ·ΈμΈλ˜μ–΄ μžˆλ‹€λŠ” 것을 μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€. + +일주일 λ’€μ—λŠ” 토큰이 만료될 것이고, μ‚¬μš©μžλŠ” μΈκ°€λ˜μ§€ μ•Šμ•„ μƒˆ 토큰을 λ°›κΈ° μœ„ν•΄ λ‹€μ‹œ λ‘œκ·ΈμΈν•΄μ•Ό ν•  κ²ƒμž…λ‹ˆλ‹€. λ§Œμ•½ μ‚¬μš©μž(λ˜λŠ” 제3자)κ°€ 토큰을 μˆ˜μ •ν•˜κ±°λ‚˜ λ§Œλ£ŒμΌμ„ λ³€κ²½ν•˜λ©΄, μ„œλͺ…이 μΌμΉ˜ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— μ•Œμ•„μ±Œ 수 μžˆμ„ κ²ƒμž…λ‹ˆλ‹€. + +λ§Œμ•½ JWT 토큰을 닀뀄보고, μž‘λ™ 방식도 μ•Œμ•„λ³΄κ³  μ‹Άλ‹€λ©΄ https://jwt.io 을 ν™•μΈν•˜μ‹­μ‹œμ˜€. + +## `PyJWT` μ„€μΉ˜ + +파이썬으둜 JWT 토큰을 μƒμ„±ν•˜κ³  κ²€μ¦ν•˜λ €λ©΄ `PyJWT` λ₯Ό μ„€μΉ˜ν•΄μ•Ό ν•©λ‹ˆλ‹€. + +[κ°€μƒν™˜κ²½](../../virtual-environments.md){.internal-link target=_blank} 을 λ§Œλ“€κ³  ν™œμ„±ν™”ν•œ λ‹€μŒ `pyjwt` λ₯Ό μ„€μΉ˜ν•˜μ‹­μ‹œμ˜€: + +
+ +```console +$ pip install pyjwt + +---> 100% +``` + +
+ +/// info | μ°Έκ³  + +RSAλ‚˜ ECDSA 같은 μ „μž μ„œλͺ… μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•˜λ €λ©΄, `pyjwt[crypto]`λΌλŠ” μ•”ν˜Έν™” 라이브러리 μ˜μ‘΄μ„±μ„ μ„€μΉ˜ν•΄μ•Ό ν•©λ‹ˆλ‹€. + +더 μžμ„Έν•œ λ‚΄μš©μ€ PyJWT μ„€μΉ˜ μ—μ„œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€. + +/// + +## νŒ¨μŠ€μ›Œλ“œ ν•΄μ‹± + +"ν•΄μ‹±(Hashing)"은 μ–΄λ–€ λ‚΄μš©(μ—¬κΈ°μ„œλŠ” νŒ¨μŠ€μ›Œλ“œ)을 해석할 수 μ—†λŠ” 일련의 λ°”μ΄νŠΈ 집합(λ‹¨μˆœ λ¬Έμžμ—΄)으둜 λ³€ν™˜ν•˜λŠ” 것을 μ˜λ―Έν•©λ‹ˆλ‹€. + +λ™μΌν•œ λ‚΄μš©(λ˜‘κ°™μ€ νŒ¨μŠ€μ›Œλ“œ)을 ν•΄μ‹±ν•˜λ©΄ λ™μΌν•œ λ¬Έμžμ—΄μ„ μ–»μŠ΅λ‹ˆλ‹€. + +ν•˜μ§€λ§Œ κ·Έ λ¬Έμžμ—΄μ„ λ‹€μ‹œ νŒ¨μŠ€μ›Œλ“œλ‘œ 되돌릴 μˆ˜λŠ” μ—†μŠ΅λ‹ˆλ‹€. + +### νŒ¨μŠ€μ›Œλ“œλ₯Ό ν•΄μ‹±ν•˜λŠ” 이유 + +λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό νƒˆμ·¨λ‹Ήν•˜λ”λΌλ„, μΉ¨μž…μžλŠ” μ‚¬μš©μžμ˜ 평문 νŒ¨μŠ€μ›Œλ“œ λŒ€μ‹  ν•΄μ‹œ κ°’λ§Œ 얻을 수 μžˆμŠ΅λ‹ˆλ‹€. + +λ”°λΌμ„œ μΉ¨μž…μžλŠ” ν›”μΉœ μ‚¬μš©μž νŒ¨μŠ€μ›Œλ“œλ₯Ό λ‹€λ₯Έ μ‹œμŠ€ν…œμ—μ„œ ν™œμš©ν•  수 μ—†μŠ΅λ‹ˆλ‹€. (λŒ€λ‹€μˆ˜ μ‚¬μš©μžκ°€ μ—¬λŸ¬ μ‹œμŠ€ν…œμ—μ„œ λ™μΌν•œ νŒ¨μŠ€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμ— 평문 νŒ¨μŠ€μ›Œλ“œκ°€ 유좜되면 μœ„ν—˜ν•©λ‹ˆλ‹€.) + +## `passlib` μ„€μΉ˜ + +PassLibλŠ” νŒ¨μŠ€μ›Œλ“œ ν•΄μ‹œλ₯Ό λ‹€λ£¨λŠ” ν›Œλ₯­ν•œ 파이썬 νŒ¨ν‚€μ§€μž…λ‹ˆλ‹€. + +λ§Žμ€ μ•ˆμ „ν•œ ν•΄μ‹œ μ•Œκ³ λ¦¬μ¦˜κ³Ό 도ꡬ듀을 μ§€μ›ν•©λ‹ˆλ‹€. + +μΆ”μ²œν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜μ€ "Bcrypt"μž…λ‹ˆλ‹€. + +[κ°€μƒν™˜κ²½](../../virtual-environments.md){.internal-link target=_blank} 을 λ§Œλ“€κ³  ν™œμ„±ν™”ν•œ λ‹€μŒ PassLib와 Bcryptλ₯Ό μ„€μΉ˜ν•˜μ‹­μ‹œμ˜€: + +
+ +```console +$ pip install "passlib[bcrypt]" + +---> 100% +``` + +
+ +/// 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 토큰 μ„œλͺ…에 μ‚¬μš©λ  μž„μ˜μ˜ λΉ„λ°€ν‚€λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€. + +μ•ˆμ „ν•œ μž„μ˜μ˜ λΉ„λ°€ν‚€λ₯Ό μƒμ„±ν•˜λ €λ©΄ λ‹€μŒ λͺ…λ Ήμ–΄λ₯Ό μ‚¬μš©ν•˜μ‹­μ‹œμ˜€: + +
+ +```console +$ openssl rand -hex 32 + +09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7 +``` + +
+ +그리고 μƒμ„±ν•œ λΉ„λ°€ν‚€λ₯Ό 볡사해 λ³€μˆ˜ `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` ν‚€λŠ” 전체 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ κ³ μœ ν•œ μ‹λ³„μžκ°€ λ˜μ–΄μ•Ό ν•˜λ©° λ¬Έμžμ—΄μ΄μ–΄μ•Ό ν•œλ‹€λŠ” μ μž…λ‹ˆλ‹€. + +## ν™•μΈν•΄λ΄…μ‹œλ‹€ + +μ„œλ²„λ₯Ό μ‹€ν–‰ν•˜κ³  λ¬Έμ„œλ‘œ μ΄λ™ν•˜μ‹­μ‹œμ˜€: http://127.0.0.1:8000/docs. + +λ‹€μŒκ³Ό 같은 μ‚¬μš©μž μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€: + + + +이전과 같은 λ°©λ²•μœΌλ‘œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ— μΈμ¦ν•˜μ‹­μ‹œμ˜€. + +λ‹€μŒ 인증 정보λ₯Ό μ‚¬μš©ν•˜μ‹­μ‹œμ˜€: + +Username: `johndoe` +Password: `secret` + +/// check + +μ½”λ“œ 어디에도 평문 νŒ¨μŠ€μ›Œλ“œ "`secret`" 이 μ—†λ‹€λŠ” 점에 μœ μ˜ν•˜μ‹­μ‹œμ˜€. ν•΄μ‹œλœ λ²„μ „λ§Œ μžˆμŠ΅λ‹ˆλ‹€. + +/// + + + +`/users/me/` λ₯Ό ν˜ΈμΆœν•˜λ©΄ λ‹€μŒκ³Ό 같은 응닡을 얻을 수 μžˆμŠ΅λ‹ˆλ‹€: + +```JSON +{ + "username": "johndoe", + "email": "johndoe@example.com", + "full_name": "John Doe", + "disabled": false +} +``` + + + +개발자 도ꡬλ₯Ό 열어보면 μ „μ†‘λœ 데이터에 ν† ν°λ§Œ ν¬ν•¨λœ 것을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€. νŒ¨μŠ€μ›Œλ“œλŠ” μ‚¬μš©μžλ₯Ό μΈμ¦ν•˜κ³  μ•‘μ„ΈμŠ€ 토큰을 λ°›κΈ° μœ„ν•œ 첫 번째 μš”μ²­μ—λ§Œ μ „μ†‘λ˜λ©°, μ΄ν›„μ—λŠ” μ „μ†‘λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€: + + + +/// 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 λ“±μ˜ λ§Žμ€ λŒ€ν˜• 인증 μ œκ³΅μ—…μ²΄λ“€μ΄ μ‚¬μš©ν•˜λŠ” λ©”μ»€λ‹ˆμ¦˜μž…λ‹ˆλ‹€. From e988050f79b32c9444fba8d014d0c69cd7a4b6c7 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 10 Mar 2025 12:29:25 +0000 Subject: [PATCH 22/22] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- docs/en/docs/release-notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index ee987b544..c900dc918 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -9,6 +9,7 @@ hide: ### 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