diff --git a/.github/workflows/people.yml b/.github/workflows/people.yml
index 0d226a745..970813da7 100644
--- a/.github/workflows/people.yml
+++ b/.github/workflows/people.yml
@@ -4,12 +4,25 @@ on:
schedule:
- cron: "0 14 1 * *"
workflow_dispatch:
+ inputs:
+ debug_enabled:
+ description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
+ required: false
+ default: false
jobs:
fastapi-people:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
+ # Allow debugging with tmate
+ - name: Setup tmate session
+ uses: mxschmitt/action-tmate@v3
+ if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}
+ with:
+ limit-access-to-actor: true
+ token: ${{ secrets.ACTIONS_TOKEN }}
+ standard_token: ${{ secrets.GITHUB_TOKEN }}
- uses: ./.github/actions/people
with:
token: ${{ secrets.ACTIONS_TOKEN }}
diff --git a/README.md b/README.md
index 018a5202e..19dba3ffc 100644
--- a/README.md
+++ b/README.md
@@ -40,7 +40,7 @@ The key features are:
* estimation based on tests on an internal development team, building production applications.
-## Gold Sponsors
+## Sponsors
diff --git a/docs/en/data/external_links.yml b/docs/en/data/external_links.yml
index 47fb681d5..8d175cbe9 100644
--- a/docs/en/data/external_links.yml
+++ b/docs/en/data/external_links.yml
@@ -156,6 +156,10 @@ articles:
title: Deploy a dockerized FastAPI application to AWS
author_link: https://www.linkedin.com/in/valon-januzaj-b02692187/
author: Valon Januzaj
+ - link: https://dompatmore.com/blog/authenticate-your-fastapi-app-with-auth0
+ title: Authenticate Your FastAPI App with auth0
+ author_link: https://twitter.com/dompatmore
+ author: Dom Patmore
japanese:
- link: https://qiita.com/mtitg/items/47770e9a562dd150631d
title: FastAPI|DB接続してCRUDするPython製APIサーバーを構築
@@ -219,6 +223,10 @@ articles:
title: Почему Вы должны попробовать FastAPI?
author_link: https://github.com/prostomarkeloff
author: prostomarkeloff
+ - link: https://trkohler.com/fast-api-introduction-to-framework
+ title: "FastAPI: знакомимся с фреймворком"
+ author_link: https://www.linkedin.com/in/trkohler/
+ author: Troy Köhler
german:
- link: https://blog.codecentric.de/2019/08/inbetriebnahme-eines-scikit-learn-modells-mit-onnx-und-fastapi/
title: Inbetriebnahme eines scikit-learn-Modells mit ONNX und FastAPI
diff --git a/docs/en/data/people.yml b/docs/en/data/people.yml
index 1ab07a3fa..fc5ed85fd 100644
--- a/docs/en/data/people.yml
+++ b/docs/en/data/people.yml
@@ -1,7 +1,7 @@
maintainers:
- login: tiangolo
answers: 1221
- prs: 221
+ prs: 222
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=05f95ca7fdead36edd9c86be46b4ef6c3c71f876&v=4
url: https://github.com/tiangolo
experts:
@@ -10,15 +10,15 @@ experts:
avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=58ed2a45798a4339700e2f62b2e12e6e54bf0396&v=4
url: https://github.com/dmontagu
- login: Kludex
- count: 216
+ count: 240
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=cf8455cb899806b774a3a71073f88583adec99f6&v=4
url: https://github.com/Kludex
- login: ycd
- count: 201
+ count: 211
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=826f228edf0bab0d19ad1d5c4ba4df1047ccffef&v=4
url: https://github.com/ycd
- login: Mause
- count: 172
+ count: 174
avatarUrl: https://avatars.githubusercontent.com/u/1405026?v=4
url: https://github.com/Mause
- login: euri10
@@ -30,7 +30,7 @@ experts:
avatarUrl: https://avatars.githubusercontent.com/u/331403?v=4
url: https://github.com/phy25
- login: falkben
- count: 54
+ count: 56
avatarUrl: https://avatars.githubusercontent.com/u/653031?u=0c8d8f33d87f1aa1a6488d3f02105e9abc838105&v=4
url: https://github.com/falkben
- login: ArcLightSlavik
@@ -38,37 +38,37 @@ experts:
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=6e53b1a2f340d77429d435babcec107c7cc50972&v=4
url: https://github.com/ArcLightSlavik
- login: sm-Fifteen
- count: 44
+ count: 46
avatarUrl: https://avatars.githubusercontent.com/u/516999?u=437c0c5038558c67e887ccd863c1ba0f846c03da&v=4
url: https://github.com/sm-Fifteen
+- login: raphaelauv
+ count: 41
+ avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
+ url: https://github.com/raphaelauv
- login: includeamin
count: 38
avatarUrl: https://avatars.githubusercontent.com/u/11836741?u=8bd5ef7e62fe6a82055e33c4c0e0a7879ff8cfb6&v=4
url: https://github.com/includeamin
-- login: raphaelauv
- count: 34
- avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
- url: https://github.com/raphaelauv
- login: prostomarkeloff
count: 33
avatarUrl: https://avatars.githubusercontent.com/u/28061158?u=72309cc1f2e04e40fa38b29969cb4e9d3f722e7b&v=4
url: https://github.com/prostomarkeloff
+- login: Dustyposa
+ count: 31
+ avatarUrl: https://avatars.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4
+ url: https://github.com/Dustyposa
- login: krishnardt
count: 30
avatarUrl: https://avatars.githubusercontent.com/u/31960541?u=47f4829c77f4962ab437ffb7995951e41eeebe9b&v=4
url: https://github.com/krishnardt
+- login: insomnes
+ count: 30
+ avatarUrl: https://avatars.githubusercontent.com/u/16958893?u=f8be7088d5076d963984a21f95f44e559192d912&v=4
+ url: https://github.com/insomnes
- login: wshayes
count: 29
avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
url: https://github.com/wshayes
-- login: Dustyposa
- count: 29
- avatarUrl: https://avatars.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4
- url: https://github.com/Dustyposa
-- login: insomnes
- count: 26
- avatarUrl: https://avatars.githubusercontent.com/u/16958893?u=f8be7088d5076d963984a21f95f44e559192d912&v=4
- url: https://github.com/insomnes
- login: dbanty
count: 25
avatarUrl: https://avatars.githubusercontent.com/u/43723790?u=0cf33e4f40efc2ea206a1189fd63a11344eb88ed&v=4
@@ -77,6 +77,10 @@ experts:
count: 24
avatarUrl: https://avatars.githubusercontent.com/u/9435877?u=719327b7d2c4c62212456d771bfa7c6b8dbb9eac&v=4
url: https://github.com/SirTelemak
+- login: acnebs
+ count: 22
+ avatarUrl: https://avatars.githubusercontent.com/u/9054108?u=bfd127b3e6200f4d00afd714f0fc95c2512df19b&v=4
+ url: https://github.com/acnebs
- login: nsidnev
count: 22
avatarUrl: https://avatars.githubusercontent.com/u/22559461?u=a9cc3238217e21dc8796a1a500f01b722adb082c&v=4
@@ -85,10 +89,6 @@ experts:
count: 21
avatarUrl: https://avatars.githubusercontent.com/u/565544?v=4
url: https://github.com/chris-allnutt
-- login: acnebs
- count: 21
- avatarUrl: https://avatars.githubusercontent.com/u/9054108?u=bfd127b3e6200f4d00afd714f0fc95c2512df19b&v=4
- url: https://github.com/acnebs
- login: retnikt
count: 19
avatarUrl: https://avatars.githubusercontent.com/u/24581770?v=4
@@ -105,18 +105,26 @@ experts:
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/7534547?v=4
url: https://github.com/chbndrhnns
+- login: waynerv
+ count: 14
+ avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
+ url: https://github.com/waynerv
- login: haizaar
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/58201?u=4f1f9843d69433ca0d380d95146cfe119e5fdac4&v=4
url: https://github.com/haizaar
-- login: waynerv
- count: 12
- avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
- url: https://github.com/waynerv
+- login: frankie567
+ count: 11
+ avatarUrl: https://avatars.githubusercontent.com/u/1144727?u=72adf1cb1d29787305c99700d669561952cea0af&v=4
+ url: https://github.com/frankie567
- login: zamiramir
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/40475662?u=e58ef61034e8d0d6a312cc956fb09b9c3332b449&v=4
url: https://github.com/zamiramir
+- login: juntatalor
+ count: 11
+ avatarUrl: https://avatars.githubusercontent.com/u/8134632?v=4
+ url: https://github.com/juntatalor
- login: valentin994
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/42819267?u=fdeeaa9242a59b243f8603496b00994f6951d5a2&v=4
@@ -131,49 +139,25 @@ experts:
url: https://github.com/stefanondisponibile
last_month_active:
- login: Kludex
- count: 24
+ count: 13
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=cf8455cb899806b774a3a71073f88583adec99f6&v=4
url: https://github.com/Kludex
- login: ycd
- count: 10
+ count: 7
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=826f228edf0bab0d19ad1d5c4ba4df1047ccffef&v=4
url: https://github.com/ycd
-- login: waynerv
- count: 9
- avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
- url: https://github.com/waynerv
-- login: juntatalor
- count: 8
- avatarUrl: https://avatars.githubusercontent.com/u/8134632?v=4
- url: https://github.com/juntatalor
-- login: Mause
- count: 8
- avatarUrl: https://avatars.githubusercontent.com/u/1405026?v=4
- url: https://github.com/Mause
-- login: valentin994
+- login: raphaelauv
count: 6
- avatarUrl: https://avatars.githubusercontent.com/u/42819267?u=fdeeaa9242a59b243f8603496b00994f6951d5a2&v=4
- url: https://github.com/valentin994
+ avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
+ url: https://github.com/raphaelauv
+- login: frankie567
+ count: 5
+ avatarUrl: https://avatars.githubusercontent.com/u/1144727?u=72adf1cb1d29787305c99700d669561952cea0af&v=4
+ url: https://github.com/frankie567
- login: insomnes
- count: 6
+ count: 4
avatarUrl: https://avatars.githubusercontent.com/u/16958893?u=f8be7088d5076d963984a21f95f44e559192d912&v=4
url: https://github.com/insomnes
-- login: Dustyposa
- count: 5
- avatarUrl: https://avatars.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4
- url: https://github.com/Dustyposa
-- login: falkben
- count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/653031?u=0c8d8f33d87f1aa1a6488d3f02105e9abc838105&v=4
- url: https://github.com/falkben
-- login: raphaelauv
- count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
- url: https://github.com/raphaelauv
-- login: chbndrhnns
- count: 3
- avatarUrl: https://avatars.githubusercontent.com/u/7534547?v=4
- url: https://github.com/chbndrhnns
top_contributors:
- login: waynerv
count: 25
@@ -203,6 +187,10 @@ top_contributors:
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/22691749?u=4795b880e13ca33a73e52fc0ef7dc9c60c8fce47&v=4
url: https://github.com/Serrones
+- login: hard-coders
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=f2d3d2038c55d86d7f9348f4e6c5e30191e4ee8b&v=4
+ url: https://github.com/hard-coders
- login: wshayes
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
@@ -223,21 +211,17 @@ top_contributors:
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/39375566?u=5a44657c0544111ee3c132d9bb9951c2804f7969&v=4
url: https://github.com/komtaki
-- login: hard-coders
- count: 4
- avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=f2d3d2038c55d86d7f9348f4e6c5e30191e4ee8b&v=4
- url: https://github.com/hard-coders
top_reviewers:
- login: Kludex
- count: 73
+ count: 75
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=cf8455cb899806b774a3a71073f88583adec99f6&v=4
url: https://github.com/Kludex
- login: tokusumi
- count: 43
+ count: 44
avatarUrl: https://avatars.githubusercontent.com/u/41147016?u=55010621aece725aa702270b54fed829b6a1fe60&v=4
url: https://github.com/tokusumi
- login: ycd
- count: 36
+ count: 39
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=826f228edf0bab0d19ad1d5c4ba4df1047ccffef&v=4
url: https://github.com/ycd
- login: Laineyzhang55
@@ -245,11 +229,11 @@ top_reviewers:
avatarUrl: https://avatars.githubusercontent.com/u/59285379?v=4
url: https://github.com/Laineyzhang55
- login: waynerv
- count: 30
+ count: 32
avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
url: https://github.com/waynerv
- login: AdrianDeAnda
- count: 25
+ count: 26
avatarUrl: https://avatars.githubusercontent.com/u/1024932?u=bb7f8a0d6c9de4e9d0320a9f271210206e202250&v=4
url: https://github.com/AdrianDeAnda
- login: dmontagu
@@ -268,6 +252,10 @@ top_reviewers:
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/52768429?u=6a3aa15277406520ad37f6236e89466ed44bc5b8&v=4
url: https://github.com/SwftAlpc
+- login: pedabraham
+ count: 15
+ avatarUrl: https://avatars.githubusercontent.com/u/16860088?u=abf922a7b920bf8fdb7867d8b43e091f1e796178&v=4
+ url: https://github.com/pedabraham
- login: delhi09
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/63476957?u=6c86e59b48e0394d4db230f37fc9ad4d7e2c27c7&v=4
@@ -276,18 +264,18 @@ top_reviewers:
count: 14
avatarUrl: https://avatars.githubusercontent.com/u/3127847?u=b0a652331da17efeb85cd6e3a4969182e5004804&v=4
url: https://github.com/cassiobotaro
-- login: pedabraham
- count: 13
- avatarUrl: https://avatars.githubusercontent.com/u/16860088?u=abf922a7b920bf8fdb7867d8b43e091f1e796178&v=4
- url: https://github.com/pedabraham
+- login: RunningIkkyu
+ count: 12
+ avatarUrl: https://avatars.githubusercontent.com/u/31848542?u=706e1ee3f248245f2d68b976d149d06fd5a2010d&v=4
+ url: https://github.com/RunningIkkyu
- login: ArcLightSlavik
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=6e53b1a2f340d77429d435babcec107c7cc50972&v=4
url: https://github.com/ArcLightSlavik
-- login: RunningIkkyu
- count: 11
- avatarUrl: https://avatars.githubusercontent.com/u/31848542?u=706e1ee3f248245f2d68b976d149d06fd5a2010d&v=4
- url: https://github.com/RunningIkkyu
+- login: hard-coders
+ count: 12
+ avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=f2d3d2038c55d86d7f9348f4e6c5e30191e4ee8b&v=4
+ url: https://github.com/hard-coders
- login: sh0nk
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/6478810?u=af15d724875cec682ed8088a86d36b2798f981c0&v=4
@@ -304,14 +292,14 @@ top_reviewers:
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/7887703?v=4
url: https://github.com/maoyibo
-- login: hard-coders
- count: 9
- avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=f2d3d2038c55d86d7f9348f4e6c5e30191e4ee8b&v=4
- url: https://github.com/hard-coders
- login: PandaHun
count: 9
avatarUrl: https://avatars.githubusercontent.com/u/13096845?u=646eba44db720e37d0dbe8e98e77ab534ea78a20&v=4
url: https://github.com/PandaHun
+- login: rjNemo
+ count: 8
+ avatarUrl: https://avatars.githubusercontent.com/u/56785022?u=d5c3a02567c8649e146fcfc51b6060ccaf8adef8&v=4
+ url: https://github.com/rjNemo
- login: blt232018
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/43393471?u=172b0e0391db1aa6c1706498d6dfcb003c8a4857&v=4
@@ -328,10 +316,14 @@ top_reviewers:
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
url: https://github.com/raphaelauv
-- login: rjNemo
+- login: jovicon
count: 6
- avatarUrl: https://avatars.githubusercontent.com/u/56785022?u=d5c3a02567c8649e146fcfc51b6060ccaf8adef8&v=4
- url: https://github.com/rjNemo
+ avatarUrl: https://avatars.githubusercontent.com/u/21287303?u=b049eac3e51a4c0473c2efe66b4d28a7d8f2b572&v=4
+ url: https://github.com/jovicon
+- login: NastasiaSaby
+ count: 6
+ avatarUrl: https://avatars.githubusercontent.com/u/8245071?u=b3afd005f9e4bf080c219ef61a592b3a8004b764&v=4
+ url: https://github.com/NastasiaSaby
- login: nimctl
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/49960770?u=e39b11d47188744ee07b2a1c7ce1a1bdf3c80760&v=4
@@ -384,6 +376,9 @@ sponsors:
- login: jmaralc
avatarUrl: https://avatars.githubusercontent.com/u/21101214?u=b15a9f07b7cbf6c9dcdbcb6550bbd2c52f55aa50&v=4
url: https://github.com/jmaralc
+- login: lucone83
+ avatarUrl: https://avatars.githubusercontent.com/u/2812607?u=49c0c4454d4c98eacdcac0e33c1d83dc6fe5a37f&v=4
+ url: https://github.com/lucone83
- login: samuelcolvin
avatarUrl: https://avatars.githubusercontent.com/u/4039449?u=807390ba9cfe23906c3bf8a0d56aaca3cf2bfa0d&v=4
url: https://github.com/samuelcolvin
@@ -393,6 +388,12 @@ sponsors:
- login: wshayes
avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
url: https://github.com/wshayes
+- login: koxudaxi
+ avatarUrl: https://avatars.githubusercontent.com/u/630670?u=507d8577b4b3670546b449c4c2ccbc5af40d72f7&v=4
+ url: https://github.com/koxudaxi
+- login: falkben
+ avatarUrl: https://avatars.githubusercontent.com/u/653031?u=0c8d8f33d87f1aa1a6488d3f02105e9abc838105&v=4
+ url: https://github.com/falkben
- login: Mazyod
avatarUrl: https://avatars.githubusercontent.com/u/860511?u=a76c978bdf91c2b332ab8769935fa415d0a8091b&v=4
url: https://github.com/Mazyod
@@ -408,9 +409,6 @@ sponsors:
- login: timdrijvers
avatarUrl: https://avatars.githubusercontent.com/u/1694939?v=4
url: https://github.com/timdrijvers
-- login: ddahan
- avatarUrl: https://avatars.githubusercontent.com/u/1933516?u=0a16a413e50dc9f9a8cad59e2009daf14f29fcf3&v=4
- url: https://github.com/ddahan
- login: mrgnw
avatarUrl: https://avatars.githubusercontent.com/u/2504532?u=7ec43837a6d0afa80f96f0788744ea6341b89f97&v=4
url: https://github.com/mrgnw
@@ -429,6 +427,9 @@ sponsors:
- login: peterHoburg
avatarUrl: https://avatars.githubusercontent.com/u/3860655?u=f55f47eb2d6a9b495e806ac5a044e3ae01ccc1fa&v=4
url: https://github.com/peterHoburg
+- login: dudil
+ avatarUrl: https://avatars.githubusercontent.com/u/4785835?u=58b7ea39123e0507f3b2996448a27256b16fd697&v=4
+ url: https://github.com/dudil
- login: p141592
avatarUrl: https://avatars.githubusercontent.com/u/5256328?u=07bc6374282ab3d08511afebaa5d511987d034f1&v=4
url: https://github.com/p141592
@@ -448,7 +449,7 @@ sponsors:
avatarUrl: https://avatars.githubusercontent.com/u/7015688?u=3afb0ba200feebbc7f958950e92db34df2a3c172&v=4
url: https://github.com/Rehket
- login: christippett
- avatarUrl: https://avatars.githubusercontent.com/u/7218120?u=d6d0dc49e6b95e2d0081f3e878ec5fc7f23f35e8&v=4
+ avatarUrl: https://avatars.githubusercontent.com/u/7218120?u=434b9d29287d7de25772d94ddc74a9bd6d969284&v=4
url: https://github.com/christippett
- login: yukiyan
avatarUrl: https://avatars.githubusercontent.com/u/7304122?u=fadb64baf3934c708349bbea1142d260a6b6ce6b&v=4
@@ -465,6 +466,9 @@ sponsors:
- login: cristeaadrian
avatarUrl: https://avatars.githubusercontent.com/u/9112724?v=4
url: https://github.com/cristeaadrian
+- login: opunsoars
+ avatarUrl: https://avatars.githubusercontent.com/u/9273060?u=97f5ecec274e159b22787ca2f466f13ab1797758&v=4
+ url: https://github.com/opunsoars
- login: otivvormes
avatarUrl: https://avatars.githubusercontent.com/u/11317418?u=6de1edefb6afd0108c0ad2816bd6efc4464a9c44&v=4
url: https://github.com/otivvormes
@@ -480,6 +484,9 @@ sponsors:
- login: uselessscat
avatarUrl: https://avatars.githubusercontent.com/u/15332878?u=8485a1b7383c274b28f383370ee2d5f9a6cd423b&v=4
url: https://github.com/uselessscat
+- login: natenka
+ avatarUrl: https://avatars.githubusercontent.com/u/15850513?u=00d1083c980d0b4ce32835dc07eee7f43f34fd2f&v=4
+ url: https://github.com/natenka
- login: la-mar
avatarUrl: https://avatars.githubusercontent.com/u/16618300?u=7755c0521d2bb0d704f35a51464b15c1e2e6c4da&v=4
url: https://github.com/la-mar
@@ -498,15 +505,15 @@ sponsors:
- login: RedCarpetUp
avatarUrl: https://avatars.githubusercontent.com/u/20360440?v=4
url: https://github.com/RedCarpetUp
-- login: SebastianLuebke
- avatarUrl: https://avatars.githubusercontent.com/u/21161532?u=ba033c1bf6851b874cfa05a8a824b9f1ff434c37&v=4
- url: https://github.com/SebastianLuebke
- login: daddycocoaman
avatarUrl: https://avatars.githubusercontent.com/u/21189155?u=756f6a17c71c538b11470f70839baacab43807ef&v=4
url: https://github.com/daddycocoaman
- login: raminsj13
avatarUrl: https://avatars.githubusercontent.com/u/24259406?u=d51f2a526312ebba150a06936ed187ca0727d329&v=4
url: https://github.com/raminsj13
+- login: comoelcometa
+ avatarUrl: https://avatars.githubusercontent.com/u/25950317?u=c6751efa038561b9bc5fa56d1033d5174e10cd65&v=4
+ url: https://github.com/comoelcometa
- login: veprimk
avatarUrl: https://avatars.githubusercontent.com/u/29689749?u=f8cb5a15a286e522e5b189bc572d5a1a90217fb2&v=4
url: https://github.com/veprimk
@@ -519,15 +526,21 @@ sponsors:
- login: SaltyCoco
avatarUrl: https://avatars.githubusercontent.com/u/31451104?u=6ee4e17c07d21b7054f54a12fa9cc377a1b24ff9&v=4
url: https://github.com/SaltyCoco
-- login: dcooper01
- avatarUrl: https://avatars.githubusercontent.com/u/32238294?u=cb3fe7e306bee6c6d5f2dc9d6129f9c0f86f7e1a&v=4
- url: https://github.com/dcooper01
+- login: mauroalejandrojm
+ avatarUrl: https://avatars.githubusercontent.com/u/31569442?u=cdada990a1527926a36e95f62c30a8b48bbc49a1&v=4
+ url: https://github.com/mauroalejandrojm
+- login: public-daniel
+ avatarUrl: https://avatars.githubusercontent.com/u/32238294?u=0377e38dd023395c9643d5388b4e9489a24b4d34&v=4
+ url: https://github.com/public-daniel
+- login: ybressler
+ avatarUrl: https://avatars.githubusercontent.com/u/40807730?u=6621dc9ab53b697912ab2a32211bb29ae90a9112&v=4
+ url: https://github.com/ybressler
- login: dbanty
avatarUrl: https://avatars.githubusercontent.com/u/43723790?u=0cf33e4f40efc2ea206a1189fd63a11344eb88ed&v=4
url: https://github.com/dbanty
-- login: saldistefano
- avatarUrl: https://avatars.githubusercontent.com/u/47062787?u=c1490b7b0938534e13ee05055b3b9f2a669401c4&v=4
- url: https://github.com/saldistefano
+- login: dudikbender
+ avatarUrl: https://avatars.githubusercontent.com/u/53487583?u=494f85229115076121b3639a3806bbac1c6ae7f6&v=4
+ url: https://github.com/dudikbender
- login: Brontomerus
avatarUrl: https://avatars.githubusercontent.com/u/61284158?u=4aee24daee1921daa722cde3fcb6701e3e37ea31&v=4
url: https://github.com/Brontomerus
@@ -540,6 +553,15 @@ sponsors:
- login: daverin
avatarUrl: https://avatars.githubusercontent.com/u/70378377?u=6d1814195c0de7162820eaad95a25b423a3869c0&v=4
url: https://github.com/daverin
+- login: anthonycepeda
+ avatarUrl: https://avatars.githubusercontent.com/u/72019805?u=892f700c79f9732211bd5221bf16eec32356a732&v=4
+ url: https://github.com/anthonycepeda
+- login: pqhaa
+ avatarUrl: https://avatars.githubusercontent.com/u/81242906?u=a71c5869241fc14dea6e413fb4b84287fefed38e&v=4
+ url: https://github.com/pqhaa
+- login: saldistefano
+ avatarUrl: https://avatars.githubusercontent.com/u/82109221?v=4
+ url: https://github.com/saldistefano
- login: linux-china
avatarUrl: https://avatars.githubusercontent.com/u/46711?v=4
url: https://github.com/linux-china
@@ -552,9 +574,9 @@ sponsors:
- login: slafs
avatarUrl: https://avatars.githubusercontent.com/u/210173?v=4
url: https://github.com/slafs
-- login: r-m-n
- avatarUrl: https://avatars.githubusercontent.com/u/328776?u=177c6ab9c2a35949ed87338b6faa60d0d8b83d87&v=4
- url: https://github.com/r-m-n
+- login: eteq
+ avatarUrl: https://avatars.githubusercontent.com/u/346587?v=4
+ url: https://github.com/eteq
- login: dmig
avatarUrl: https://avatars.githubusercontent.com/u/388564?v=4
url: https://github.com/dmig
@@ -564,12 +586,12 @@ sponsors:
- login: lukin0110
avatarUrl: https://avatars.githubusercontent.com/u/992275?u=d20b7e18b213ae7004585b382eccb542db5ffe48&v=4
url: https://github.com/lukin0110
+- login: okken
+ avatarUrl: https://avatars.githubusercontent.com/u/1568356?u=0a991a21bdc62e2bea9ad311652f2c45f453dc84&v=4
+ url: https://github.com/okken
- login: cbonoz
avatarUrl: https://avatars.githubusercontent.com/u/2351087?u=fd3e8030b2cc9fbfbb54a65e9890c548a016f58b&v=4
url: https://github.com/cbonoz
-- login: Debakel
- avatarUrl: https://avatars.githubusercontent.com/u/2857237?u=567f61fbc59c4be72e917d964904ead0cfa81ac0&v=4
- url: https://github.com/Debakel
- login: Atem18
avatarUrl: https://avatars.githubusercontent.com/u/2875254?v=4
url: https://github.com/Atem18
@@ -588,8 +610,11 @@ sponsors:
- login: spyker77
avatarUrl: https://avatars.githubusercontent.com/u/4953435?u=568baae6469628e020fe0bab16e395b7ae10c7d3&v=4
url: https://github.com/spyker77
+- login: iwpnd
+ avatarUrl: https://avatars.githubusercontent.com/u/6152183?u=b2286006daafff5f991557344fee20b5da59639a&v=4
+ url: https://github.com/iwpnd
- login: holec
- avatarUrl: https://avatars.githubusercontent.com/u/6438041?u=4e884920f8585dc3a5dba48924df11f2a16e40a4&v=4
+ avatarUrl: https://avatars.githubusercontent.com/u/6438041?u=f5af71ec85b3a9d7b8139cb5af0512b02fa9ab1e&v=4
url: https://github.com/holec
- login: BartlomiejRasztabiga
avatarUrl: https://avatars.githubusercontent.com/u/8852711?u=ed213d60f7a423df31ceb1004aa3ec60e612cb98&v=4
@@ -600,15 +625,30 @@ sponsors:
- login: and-semakin
avatarUrl: https://avatars.githubusercontent.com/u/9129071?u=ea77ddf7de4bc375d546bf2825ed420eaddb7666&v=4
url: https://github.com/and-semakin
+- login: VivianSolide
+ avatarUrl: https://avatars.githubusercontent.com/u/9358572?u=ffb2e2ec522a15dcd3f0af1f9fd1df4afe418afa&v=4
+ url: https://github.com/VivianSolide
- login: hard-coders
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=f2d3d2038c55d86d7f9348f4e6c5e30191e4ee8b&v=4
url: https://github.com/hard-coders
- login: JimFawkes
avatarUrl: https://avatars.githubusercontent.com/u/12075115?u=dc58ecfd064d72887c34bf500ddfd52592509acd&v=4
url: https://github.com/JimFawkes
+- login: logan-connolly
+ avatarUrl: https://avatars.githubusercontent.com/u/16244943?u=8ae66dfbba936463cc8aa0dd7a6d2b4c0cc757eb&v=4
+ url: https://github.com/logan-connolly
+- login: sebastianmarines
+ avatarUrl: https://avatars.githubusercontent.com/u/18373185?u=e0be7c230456a2bdc0825e3d6541ea8966e22028&v=4
+ url: https://github.com/sebastianmarines
- login: Filimoa
avatarUrl: https://avatars.githubusercontent.com/u/21352040?u=75e02d102d2ee3e3d793e555fa5c63045913ccb0&v=4
url: https://github.com/Filimoa
+- login: ghandic
+ avatarUrl: https://avatars.githubusercontent.com/u/23500353?u=e2e1d736f924d9be81e8bfc565b6d8836ba99773&v=4
+ url: https://github.com/ghandic
+- login: MoronVV
+ avatarUrl: https://avatars.githubusercontent.com/u/24293616?v=4
+ url: https://github.com/MoronVV
- login: mertguvencli
avatarUrl: https://avatars.githubusercontent.com/u/29762151?u=16a906d90df96c8cff9ea131a575c4bc171b1523&v=4
url: https://github.com/mertguvencli
@@ -618,15 +658,18 @@ sponsors:
- login: leynier
avatarUrl: https://avatars.githubusercontent.com/u/36774373?u=60eee7ab14aada5aab8af6fbd11d14732750a7ab&v=4
url: https://github.com/leynier
-- login: AjitZK
+- login: JitPackJoyride
avatarUrl: https://avatars.githubusercontent.com/u/40203625?u=9638bfeacfa5940358188f8205ce662bba022b53&v=4
- url: https://github.com/AjitZK
+ url: https://github.com/JitPackJoyride
+- login: es3n1n
+ avatarUrl: https://avatars.githubusercontent.com/u/40367813?u=f562f0f93b108a923be6aba1ec041128286c3c50&v=4
+ url: https://github.com/es3n1n
- login: ilias-ant
avatarUrl: https://avatars.githubusercontent.com/u/42189572?u=064bf3a60fcb3c445ab038386321098920b3f4e4&v=4
url: https://github.com/ilias-ant
-- login: Erik172
- avatarUrl: https://avatars.githubusercontent.com/u/51425933?u=e2e7df1c045efb2dc413ad59d77a1ab8bdc4bc87&v=4
- url: https://github.com/Erik172
+- login: akanz1
+ avatarUrl: https://avatars.githubusercontent.com/u/51492342?u=2280f57134118714645e16b535c1a37adf6b369b&v=4
+ url: https://github.com/akanz1
- login: athemeart
avatarUrl: https://avatars.githubusercontent.com/u/61623624?v=4
url: https://github.com/athemeart
diff --git a/docs/en/data/sponsors.yml b/docs/en/data/sponsors.yml
index 7054fd516..5f56d9667 100644
--- a/docs/en/data/sponsors.yml
+++ b/docs/en/data/sponsors.yml
@@ -2,6 +2,7 @@ gold:
- url: https://www.deta.sh/?ref=fastapi
title: The launchpad for all your (team's) ideas
img: https://fastapi.tiangolo.com/img/sponsors/deta.svg
+silver:
- url: https://www.investsuite.com/jobs
title: Wealthtech jobs with FastAPI
img: https://fastapi.tiangolo.com/img/sponsors/investsuite.svg
@@ -11,7 +12,7 @@ gold:
- url: https://talkpython.fm/fastapi-sponsor
title: FastAPI video courses on demand from people you trust
img: https://fastapi.tiangolo.com/img/sponsors/talkpython.png
-silver:
+bronze:
- 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
diff --git a/docs/en/docs/css/custom.css b/docs/en/docs/css/custom.css
index ea408a11a..35ff9ef70 100644
--- a/docs/en/docs/css/custom.css
+++ b/docs/en/docs/css/custom.css
@@ -56,10 +56,41 @@ a.internal-link::after {
text-align: center;
}
-a.announce:link, a.announce:visited {
+a.announce-link:link,
+a.announce-link:visited {
color: #fff;
}
-a.announce:hover {
+a.announce-link:hover {
color: var(--md-accent-fg-color);
}
+
+.announce-wrapper {
+ display: flex;
+ justify-content: space-between;
+ flex-wrap: wrap;
+ align-items: center;
+}
+
+.announce-wrapper div.item {
+ display: none;
+}
+
+.announce-wrapper .sponsor-badge {
+ display: block;
+ position: absolute;
+ top: -5px;
+ right: 0;
+ font-size: 0.5rem;
+ color: #999;
+ background-color: #666;
+ border-radius: 10px;
+ padding: 0 10px;
+ z-index: 10;
+}
+
+.announce-wrapper>div {
+ min-height: 40px;
+ display: flex;
+ align-items: center;
+}
diff --git a/docs/en/docs/fastapi-people.md b/docs/en/docs/fastapi-people.md
index f73526002..e38c31c3d 100644
--- a/docs/en/docs/fastapi-people.md
+++ b/docs/en/docs/fastapi-people.md
@@ -130,11 +130,19 @@ They are supporting my work with **FastAPI** (and others), mainly through
+{% endfor %}
+{% endif %}
+
+### Individual Sponsors
+
{% if people %}
{% if people.sponsors_50 %}
-### Bronze Sponsors
-
{% for user in people.sponsors_50 %}
@@ -146,8 +154,6 @@ They are supporting my work with **FastAPI** (and others), mainly through
{% for user in people.sponsors %}
diff --git a/docs/en/docs/img/sponsors/deta-banner.svg b/docs/en/docs/img/sponsors/deta-banner.svg
new file mode 100644
index 000000000..e9b344ad3
--- /dev/null
+++ b/docs/en/docs/img/sponsors/deta-banner.svg
@@ -0,0 +1,125 @@
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/en/docs/img/sponsors/deta.svg b/docs/en/docs/img/sponsors/deta.svg
index c2b77a867..066d6be7a 100644
--- a/docs/en/docs/img/sponsors/deta.svg
+++ b/docs/en/docs/img/sponsors/deta.svg
@@ -5,14 +5,14 @@
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
- width="240"
- height="100"
- viewBox="0 0 240 100"
fill="none"
+ viewBox="0 0 240 100"
version="1.1"
- id="svg19">
+ id="svg16"
+ width="240"
+ height="100">
+ id="metadata22">
@@ -24,76 +24,42 @@
-
-
-
-
-
-
-
-
- Deploy your FastAPI app for free
+ id="defs20" />
+ id="g854"
+ transform="scale(0.5)">
+
+ d="m 152.507,18 c 19.61,0 35.507,15.825 35.507,35.347 0,19.522 -15.897,35.347 -35.507,35.347 C 132.897,88.694 117,72.87 117,53.347 117,33.825 132.897,18 152.507,18 Z"
+ fill="#f73b95"
+ id="path4" />
+ id="path6" />
+ id="path8" />
+ id="path10" />
+ id="path12" />
+
diff --git a/docs/en/docs/img/tutorial/body-fields/image02.png b/docs/en/docs/img/tutorial/body-fields/image02.png
new file mode 100644
index 000000000..f307bb8ec
Binary files /dev/null and b/docs/en/docs/img/tutorial/body-fields/image02.png differ
diff --git a/docs/en/docs/index.md b/docs/en/docs/index.md
index a721c3c12..82e8a9fca 100644
--- a/docs/en/docs/index.md
+++ b/docs/en/docs/index.md
@@ -40,13 +40,16 @@ The key features are:
* estimation based on tests on an internal development team, building production applications.
-## Gold Sponsors
+## Sponsors
{% if sponsors %}
{% for sponsor in sponsors.gold -%}
+{% endfor -%}
+{%- for sponsor in sponsors.silver -%}
+
{% endfor %}
{% endif %}
diff --git a/docs/en/docs/js/custom.js b/docs/en/docs/js/custom.js
index 72140df8b..8e3be4c13 100644
--- a/docs/en/docs/js/custom.js
+++ b/docs/en/docs/js/custom.js
@@ -128,6 +128,35 @@ function setupTermynal() {
loadVisibleTermynals();
}
+function shuffle(array) {
+ var currentIndex = array.length, temporaryValue, randomIndex;
+ while (0 !== currentIndex) {
+ randomIndex = Math.floor(Math.random() * currentIndex);
+ currentIndex -= 1;
+ temporaryValue = array[currentIndex];
+ array[currentIndex] = array[randomIndex];
+ array[randomIndex] = temporaryValue;
+ }
+ return array;
+}
+
+async function showRandomAnnouncement(groupId, timeInterval) {
+ const announceFastAPI = document.getElementById(groupId);
+ if (announceFastAPI) {
+ let children = [].slice.call(announceFastAPI.children);
+ children = shuffle(children)
+ let index = 0
+ const announceRandom = () => {
+ children.forEach((el, i) => {el.style.display = "none"});
+ children[index].style.display = "block"
+ index = (index + 1) % children.length
+ }
+ announceRandom()
+ setInterval(announceRandom, timeInterval
+ )
+ }
+}
+
async function main() {
if (div) {
data = await getData()
@@ -144,6 +173,8 @@ async function main() {
}
setupTermynal();
+ showRandomAnnouncement('announce-left', 5000)
+ showRandomAnnouncement('announce-right', 10000)
}
main()
diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md
index f8708c690..5b2d9ba04 100644
--- a/docs/en/docs/release-notes.md
+++ b/docs/en/docs/release-notes.md
@@ -2,8 +2,15 @@
## Latest Changes
-* 👥 Update FastAPI People. PR [#3031](https://github.com/tiangolo/fastapi/pull/3031) by [@github-actions[bot]](https://github.com/apps/github-actions).
-* 🌐 Add Chinese translation for Tutorial - Debugging. PR [#2737](https://github.com/tiangolo/fastapi/pull/2737) by [@blt232018](https://github.com/blt232018).
+* ✨ Add new Deta banner badge with new sponsorship tier 🙇. PR [#3194](https://github.com/tiangolo/fastapi/pull/3194) by [@tiangolo](https://github.com/tiangolo).
+* 👥 Update FastAPI People. PR [#3189](https://github.com/tiangolo/fastapi/pull/3189) by [@github-actions[bot]](https://github.com/apps/github-actions).
+* 🔊 Update FastAPI People to allow better debugging. PR [#3188](https://github.com/tiangolo/fastapi/pull/3188) by [@tiangolo](https://github.com/tiangolo).
+## 0.64.0
+
+### Features
+
+* ✨ Add support for adding multiple `examples` in request bodies and path, query, cookie, and header params. New docs: [Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#body-with-multiple-examples). Initial PR [#1267](https://github.com/tiangolo/fastapi/pull/1267) by [@austinorr](https://github.com/austinorr).
+
### Fixes
* 📌 Pin SQLAlchemy range for tests, as it doesn't use SemVer. PR [#3001](https://github.com/tiangolo/fastapi/pull/3001) by [@tiangolo](https://github.com/tiangolo).
@@ -12,6 +19,8 @@
### Docs
+* 📝 Add link to article in Russian "FastAPI: знакомимся с фреймворком". PR [#2564](https://github.com/tiangolo/fastapi/pull/2564) by [@trkohler](https://github.com/trkohler).
+* 📝 Add external link to blog post "Authenticate Your FastAPI App with Auth0". PR [#2172](https://github.com/tiangolo/fastapi/pull/2172) by [@dompatmore](https://github.com/dompatmore).
* 📝 Fix broken link to article: Machine learning model serving in Python using FastAPI and Streamlit. PR [#2557](https://github.com/tiangolo/fastapi/pull/2557) by [@davidefiocco](https://github.com/davidefiocco).
* 📝 Add FastAPI Medium Article: Deploy a dockerized FastAPI application to AWS. PR [#2515](https://github.com/tiangolo/fastapi/pull/2515) by [@vjanz](https://github.com/vjanz).
* ✏ Fix typo in Tutorial - Handling Errors. PR [#2486](https://github.com/tiangolo/fastapi/pull/2486) by [@johnthagen](https://github.com/johnthagen).
@@ -21,6 +30,15 @@
### Translations
+* 🌐 Fix Chinese translation of Tutorial - Query Parameters, remove obsolete content. PR [#3051](https://github.com/tiangolo/fastapi/pull/3051) by [@louis70109](https://github.com/louis70109).
+* 🌐 Add French translation for Tutorial - Background Tasks. PR [#3098](https://github.com/tiangolo/fastapi/pull/3098) by [@Smlep](https://github.com/Smlep).
+* 🌐 Fix Korean translation for docs/ko/docs/index.md. PR [#3159](https://github.com/tiangolo/fastapi/pull/3159) by [@SueNaEunYang](https://github.com/SueNaEunYang).
+* 🌐 Add Korean translation for Tutorial - Query Parameters. PR [#2390](https://github.com/tiangolo/fastapi/pull/2390) by [@hard-coders](https://github.com/hard-coders).
+* 🌐 Add French translation for FastAPI People. PR [#2232](https://github.com/tiangolo/fastapi/pull/2232) by [@JulianMaurin](https://github.com/JulianMaurin).
+* 🌐 Add Korean translation for Tutorial - Path Parameters. PR [#2355](https://github.com/tiangolo/fastapi/pull/2355) by [@hard-coders](https://github.com/hard-coders).
+* 🌐 Add French translation for Features. PR [#2157](https://github.com/tiangolo/fastapi/pull/2157) by [@Jefidev](https://github.com/Jefidev).
+* 👥 Update FastAPI People. PR [#3031](https://github.com/tiangolo/fastapi/pull/3031) by [@github-actions[bot]](https://github.com/apps/github-actions).
+* 🌐 Add Chinese translation for Tutorial - Debugging. PR [#2737](https://github.com/tiangolo/fastapi/pull/2737) by [@blt232018](https://github.com/blt232018).
* 🌐 Add Chinese translation for Tutorial - Security - OAuth2 with Password (and hashing), Bearer with JWT tokens. PR [#2642](https://github.com/tiangolo/fastapi/pull/2642) by [@waynerv](https://github.com/waynerv).
* 🌐 Add Korean translation for Tutorial - Header Parameters. PR [#2589](https://github.com/tiangolo/fastapi/pull/2589) by [@mode9](https://github.com/mode9).
* 🌐 Add Chinese translation for Tutorial - Metadata and Docs URLs. PR [#2559](https://github.com/tiangolo/fastapi/pull/2559) by [@blt232018](https://github.com/blt232018).
@@ -51,7 +69,6 @@
* 🌐 Add Japanese translation for Tutorial - Body - Updates. PR [#1956](https://github.com/tiangolo/fastapi/pull/1956) by [@SwftAlpc](https://github.com/SwftAlpc).
* 🌐 Add Japanese translation for Tutorial - Form Data. PR [#1943](https://github.com/tiangolo/fastapi/pull/1943) by [@SwftAlpc](https://github.com/SwftAlpc).
* 🌐 Add Japanese translation for Tutorial - Cookie Parameters. PR [#1933](https://github.com/tiangolo/fastapi/pull/1933) by [@SwftAlpc](https://github.com/SwftAlpc).
-* 🔧 Update FastAPI People GitHub Sponsors order. PR [#2620](https://github.com/tiangolo/fastapi/pull/2620) by [@tiangolo](https://github.com/tiangolo).
### Internal
@@ -64,6 +81,7 @@
* 🔧 Add FastAPI user survey banner. PR [#2623](https://github.com/tiangolo/fastapi/pull/2623) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Add new Bronze Sponsor(s) 🥉🎉. PR [#2622](https://github.com/tiangolo/fastapi/pull/2622) by [@tiangolo](https://github.com/tiangolo).
* 📝 Update social links: add Discord, fix GitHub. PR [#2621](https://github.com/tiangolo/fastapi/pull/2621) by [@tiangolo](https://github.com/tiangolo).
+* 🔧 Update FastAPI People GitHub Sponsors order. PR [#2620](https://github.com/tiangolo/fastapi/pull/2620) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Update InvestSuite sponsor data. PR [#2608](https://github.com/tiangolo/fastapi/pull/2608) by [@tiangolo](https://github.com/tiangolo).
* 👥 Update FastAPI People. PR [#2590](https://github.com/tiangolo/fastapi/pull/2590) by [@github-actions[bot]](https://github.com/apps/github-actions).
diff --git a/docs/en/docs/tutorial/schema-extra-example.md b/docs/en/docs/tutorial/schema-extra-example.md
index 11c89c084..47ee8503a 100644
--- a/docs/en/docs/tutorial/schema-extra-example.md
+++ b/docs/en/docs/tutorial/schema-extra-example.md
@@ -1,58 +1,109 @@
-# Schema Extra - Example
+# Declare Request Example Data
-You can define extra information to go in JSON Schema.
+You can declare examples of the data your app can receive.
-A common use case is to add an `example` that will be shown in the docs.
-
-There are several ways you can declare extra JSON Schema information.
+Here are several ways to do it.
## Pydantic `schema_extra`
-You can declare an example for a Pydantic model using `Config` and `schema_extra`, as described in
Pydantic's docs: Schema customization :
+You can declare an `example` for a Pydantic model using `Config` and `schema_extra`, as described in
Pydantic's docs: Schema customization :
```Python hl_lines="15-23"
{!../../../docs_src/schema_extra_example/tutorial001.py!}
```
-That extra info will be added as-is to the output JSON Schema.
+That extra info will be added as-is to the output **JSON Schema** for that model, and it will be used in the API docs.
+
+!!! tip
+ You could use the same technique to extend the JSON Schema and add your own custom extra info.
+
+ For example you could use it to add metadata for a frontend user interface, etc.
## `Field` additional arguments
-In `Field`, `Path`, `Query`, `Body` and others you'll see later, you can also declare extra info for the JSON Schema by passing any other arbitrary arguments to the function, for example, to add an `example`:
+When using `Field()` with Pydantic models, you can also declare extra info for the **JSON Schema** by passing any other arbitrary arguments to the function.
+
+You can use this to add `example` for each field:
```Python hl_lines="4 10-13"
{!../../../docs_src/schema_extra_example/tutorial002.py!}
```
!!! warning
- Keep in mind that those extra arguments passed won't add any validation, only annotation, for documentation purposes.
+ Keep in mind that those extra arguments passed won't add any validation, only extra information, for documentation purposes.
+
+## `example` and `examples` in OpenAPI
+
+When using any of:
-## `Body` additional arguments
+* `Path()`
+* `Query()`
+* `Header()`
+* `Cookie()`
+* `Body()`
+* `Form()`
+* `File()`
-The same way you can pass extra info to `Field`, you can do the same with `Path`, `Query`, `Body`, etc.
+you can also declare a data `example` or a group of `examples` with additional information that will be added to **OpenAPI**.
-For example, you can pass an `example` for a body request to `Body`:
+### `Body` with `example`
+
+Here we pass an `example` of the data expected in `Body()`:
```Python hl_lines="21-26"
{!../../../docs_src/schema_extra_example/tutorial003.py!}
```
-## Example in the docs UI
+### Example in the docs UI
With any of the methods above it would look like this in the `/docs`:
+### `Body` with multiple `examples`
+
+Alternatively to the single `example`, you can pass `examples` using a `dict` with **multiple examples**, each with extra information that will be added to **OpenAPI** too.
+
+The keys of the `dict` identify each example, and each value is another `dict`.
+
+Each specific example `dict` in the `examples` can contain:
+
+* `summary`: Short description for the example.
+* `description`: A long description that can contain Markdown text.
+* `value`: This is the actual example shown, e.g. a `dict`.
+* `externalValue`: alternative to `value`, a URL pointing to the example. Although this might not be supported by as many tools as `value`.
+
+```Python hl_lines="22-48"
+{!../../../docs_src/schema_extra_example/tutorial004.py!}
+```
+
+### Examples in the docs UI
+
+With `examples` added to `Body()` the `/docs` would look like:
+
+
+
## Technical Details
-About `example` vs `examples`...
+!!! warning
+ These are very technical details about the standards **JSON Schema** and **OpenAPI**.
+
+ If the ideas above already work for you, that might me enough, and you probably don't need these details, feel free to skip them.
+
+When you add an example inside of a Pydantic model, using `schema_extra` or `Field(example="something")` that example is added to the **JSON Schema** for that Pydantic model.
+
+And that **JSON Schema** of the Pydantic model is included in the **OpenAPI** of your API, and then it's used in the docs UI.
+
+**JSON Schema** doesn't really have a field `example` in the standards. Recent versions of JSON Schema define a field
`examples` , but OpenAPI 3.0.3 is based on an older version of JSON Schema that didn't have `examples`.
+
+So, OpenAPI 3.0.3 defined its own
`example` for the modified version of **JSON Schema** it uses, for the same purpose (but it's a single `example`, not `examples`), and that's what is used by the API docs UI (using Swagger UI).
-JSON Schema defines a field
`examples` in the most recent versions, but OpenAPI is based on an older version of JSON Schema that didn't have `examples`.
+So, although `example` is not part of JSON Schema, it is part of OpenAPI's custom version of JSON Schema, and that's what will be used by the docs UI.
-So, OpenAPI defined its own
`example` for the same purpose (as `example`, not `examples`), and that's what is used by the docs UI (using Swagger UI).
+But when you use `example` or `examples` with any of the other utilities (`Query()`, `Body()`, etc.) those examples are not added to the JSON Schema that describes that data (not even to OpenAPI's own version of JSON Schema), they are added directly to the *path operation* declaration in OpenAPI (outside the parts of OpenAPI that use JSON Schema).
-So, although `example` is not part of JSON Schema, it is part of OpenAPI, and that's what will be used by the docs UI.
+For `Path()`, `Query()`, `Header()`, and `Cookie()`, the `example` or `examples` are added to the
OpenAPI definition, to the `Parameter Object` (in the specification) .
-## Other info
+And for `Body()`, `File()`, and `Form()`, the `example` or `examples` are equivalently added to the
OpenAPI definition, to the `Request Body Object`, in the field `content`, on the `Media Type Object` (in the specification) .
-The same way, you could add your own custom extra info that would be added to the JSON Schema for each model, for example to customize a frontend user interface, etc.
+On the other hand, there's a newer version of OpenAPI: **3.1.0**, recently released. It is based on the latest JSON Schema and most of the modifications from OpenAPI's custom version of JSON Schema are removed, in exchange of the features from the recent versions of JSON Schema, so all these small differences are reduced. Nevertheless, Swagger UI currently doesn't support OpenAPI 3.1.0, so, for now, it's better to continue using the ideas above.
diff --git a/docs/en/overrides/main.html b/docs/en/overrides/main.html
index abf6f3108..25e973b81 100644
--- a/docs/en/overrides/main.html
+++ b/docs/en/overrides/main.html
@@ -1,13 +1,26 @@
{% extends "base.html" %}
{% block announce %}
-
-
- {% include ".icons/material/email.svg" %}
- Subscribe to the FastAPI and friends newsletter 🎉
-
-
+
{% endblock %}
diff --git a/docs/fr/docs/fastapi-people.md b/docs/fr/docs/fastapi-people.md
new file mode 100644
index 000000000..35d680df9
--- /dev/null
+++ b/docs/fr/docs/fastapi-people.md
@@ -0,0 +1,135 @@
+# La communauté FastAPI
+
+FastAPI a une communauté extraordinaire qui accueille des personnes de tous horizons.
+
+## Créateur - Mainteneur
+
+Salut! 👋
+
+C'est moi :
+
+{% if people %}
+
+{% for user in people.maintainers %}
+
+
+{% endfor %}
+
+
+{% endif %}
+
+Je suis le créateur et le responsable de **FastAPI**. Vous pouvez en lire plus à ce sujet dans [Aide FastAPI - Obtenir de l'aide - Se rapprocher de l'auteur](help-fastapi.md#connect-with-the-author){.internal-link target=_blank}.
+
+...Mais ici, je veux vous montrer la communauté.
+
+---
+
+**FastAPI** reçoit beaucoup de soutien de la part de la communauté. Et je tiens à souligner leurs contributions.
+
+Ce sont ces personnes qui :
+
+* [Aident les autres à résoudre des problèmes (questions) dans GitHub](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank}.
+* [Créent des Pull Requests](help-fastapi.md#create-a-pull-request){.internal-link target=_blank}.
+* Review les Pull Requests, [particulièrement important pour les traductions](contributing.md#translations){.internal-link target=_blank}.
+
+Une salve d'applaudissements pour eux. 👏 🙇
+
+## Utilisateurs les plus actifs le mois dernier
+
+Ce sont les utilisateurs qui ont [aidé le plus les autres avec des problèmes (questions) dans GitHub](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank} au cours du dernier mois. ☕
+
+{% if people %}
+
+{% for user in people.last_month_active %}
+
+
+{% endfor %}
+
+
+{% endif %}
+
+## Experts
+
+Voici les **Experts FastAPI**. 🤓
+
+Ce sont les utilisateurs qui ont [aidé le plus les autres avec des problèmes (questions) dans GitHub](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank} depuis *toujours*.
+
+Ils ont prouvé qu'ils étaient des experts en aidant beaucoup d'autres personnes. ✨
+
+{% if people %}
+
+{% for user in people.experts %}
+
+
+{% endfor %}
+
+
+{% endif %}
+
+## Principaux contributeurs
+
+Ces utilisateurs sont les **Principaux contributeurs**. 👷
+
+Ces utilisateurs ont [créé le plus grand nombre de demandes Pull Request](help-fastapi.md#create-a-pull-request){.internal-link target=_blank} qui ont été *merged*.
+
+Ils ont contribué au code source, à la documentation, aux traductions, etc. 📦
+
+{% if people %}
+
+{% for user in people.top_contributors %}
+
+
+{% endfor %}
+
+
+{% endif %}
+
+Il existe de nombreux autres contributeurs (plus d'une centaine), vous pouvez les voir tous dans la
Page des contributeurs de FastAPI GitHub . 👷
+
+## Principaux Reviewers
+
+Ces utilisateurs sont les **Principaux Reviewers**. 🕵️
+
+### Reviewers des traductions
+
+Je ne parle que quelques langues (et pas très bien 😅). Ainsi, les reviewers sont ceux qui ont le [**pouvoir d'approuver les traductions**](contributing.md#translations){.internal-link target=_blank} de la documentation. Sans eux, il n'y aurait pas de documentation dans plusieurs autres langues.
+
+---
+
+Les **Principaux Reviewers** 🕵️ ont examiné le plus grand nombre de demandes Pull Request des autres, assurant la qualité du code, de la documentation, et surtout, des **traductions**.
+
+{% if people %}
+
+{% for user in people.top_reviewers %}
+
+
+{% endfor %}
+
+
+{% endif %}
+
+## Sponsors
+
+Ce sont les **Sponsors**. 😎
+
+Ils soutiennent mon travail avec **FastAPI** (et d'autres) avec
GitHub Sponsors .
+
+{% if people %}
+
+{% for user in people.sponsors %}
+
+
+{% endfor %}
+
+
+{% endif %}
+
+## À propos des données - détails techniques
+
+L'intention de cette page est de souligner l'effort de la communauté pour aider les autres.
+
+Notamment en incluant des efforts qui sont normalement moins visibles, et, dans de nombreux cas, plus difficile, comme aider d'autres personnes à résoudre des problèmes et examiner les Pull Requests de traduction.
+
+Les données sont calculées chaque mois, vous pouvez lire le
code source ici .
+
+Je me réserve également le droit de mettre à jour l'algorithme, les sections, les seuils, etc. (juste au cas où 🤷).
diff --git a/docs/fr/docs/features.md b/docs/fr/docs/features.md
new file mode 100644
index 000000000..d669220a6
--- /dev/null
+++ b/docs/fr/docs/features.md
@@ -0,0 +1,201 @@
+# Fonctionnalités
+
+## Fonctionnalités de FastAPI
+
+**FastAPI** vous offre ceci:
+
+### Basé sur des standards ouverts
+
+*
OpenAPI pour la création d'API, incluant la déclaration de
path operations , paramètres, corps de requêtes, sécurité, etc.
+* Documentation automatique des modèles de données avec
JSON Schema (comme OpenAPI est aussi basée sur JSON Schema).
+* Conçue avec ces standards après une analyse méticuleuse. Plutôt qu'en rajoutant des surcouches après coup.
+* Cela permet d'utiliser de la **génération automatique de code client** dans beaucoup de langages.
+
+### Documentation automatique
+
+Documentation d'API interactive et interface web d'exploration. Comme le framework est basé sur OpenAPI, de nombreuses options sont disponibles. Deux d'entre-elles sont incluses par défaut.
+
+*
Swagger UI , propose une documentation interactive. Vous permet de directement tester l'API depuis votre navigateur.
+
+
+
+* Une autre documentation d'API est fournie par
ReDoc .
+
+
+
+### Faite en python moderne
+
+Tout est basé sur la déclaration de type standard de **Python 3.6** (grâce à Pydantic). Pas de nouvelles syntaxes à apprendre. Juste du Python standard et moderne.
+
+Si vous souhaitez un rappel de 2 minutes sur l'utilisation des types en Python (même si vous ne comptez pas utiliser FastAPI), jetez un oeil au tutoriel suivant: [Python Types](python-types.md){.internal-link target=_blank}.
+
+Vous écrivez du python standard avec des annotations de types:
+
+```Python
+from typing import List, Dict
+from datetime import date
+
+from pydantic import BaseModel
+
+# Déclare une variable comme étant une str
+# et profitez de l'aide de votre IDE dans cette fonction
+def main(user_id: str):
+ return user_id
+
+
+# Un modèle Pydantic
+class User(BaseModel):
+ id: int
+ name: str
+ joined: date
+```
+Qui peuvent ensuite être utilisés comme cela:
+
+```Python
+my_user: User = User(id=3, name="John Doe", joined="2018-07-19")
+
+second_user_data = {
+ "id": 4,
+ "name": "Mary",
+ "joined": "2018-11-30",
+}
+
+my_second_user: User = User(**second_user_data)
+```
+
+!!! info
+ `**second_user_data` signifie:
+
+ Utilise les clés et valeurs du dictionnaire `second_user_data` directement comme des arguments clé-valeur. C'est équivalent à: `User(id=4, name="Mary", joined="2018-11-30")`
+
+### Support d'éditeurs
+
+Tout le framework a été conçu pour être facile et intuitif d'utilisation, toutes les décisions de design ont été testées sur de nombreux éditeurs avant même de commencer le développement final afin d'assurer la meilleure expérience de développement possible.
+
+Dans le dernier sondage effectué auprès de développeurs python il était clair que
la fonctionnalité la plus utilisée est "l'autocomplètion" .
+
+Tout le framwork **FastAPI** a été conçu avec cela en tête. L'autocomplétion fonctionne partout.
+
+Vous devrez rarement revenir à la documentation.
+
+Voici comment votre éditeur peut vous aider:
+
+* dans
Visual Studio Code :
+
+
+
+* dans
PyCharm :
+
+
+
+Vous aurez des propositions de complétion que vous n'auriez jamais imaginées. Par exemple la clé `prix` dans le corps d'un document JSON (qui est peut-être imbriqué) venant d'une requête.
+
+Plus jamais vous ne vous tromperez en tapant le nom d'une clé, vous ne ferez des aller-retour entre votre code et la documentation ou vous ne scrollerez de haut en bas afin d'enfin savoir si vous devez taper `username` ou `user_name`.
+
+### Court
+
+Des **valeurs par défaut** sont définies pour tout, des configurations optionnelles sont présentent partout. Tous ces paramètres peuvent être ajustés afin de faire ce que vous voulez et définir l'API dont vous avez besoin.
+
+Mais, **tout fonctionne** par défaut.
+
+### Validation
+
+* Validation pour la plupart (ou tous?) les **types de données** Python incluant:
+ * objets JSON (`dict`).
+ * listes JSON (`list`) définissant des types d'éléments.
+ * Champs String (`str`), définition de longueur minimum ou maximale.
+ * Nombres (`int`, `float`) avec valeur minimale and maximale, etc.
+
+* Validation pour des types plus exotiques, tel que:
+ * URL.
+ * Email.
+ * UUID.
+ * ...et autres.
+
+Toutes les validations sont gérées par le bien établi et robuste **Pydantic**.
+
+### Sécurité et authentification
+
+La sécurité et l'authentification sont intégrées. Sans aucun compromis avec les bases de données ou les modèles de données.
+
+Tous les protocoles de sécurités sont définis dans OpenAPI, incluant:
+
+* HTTP Basic.
+* **OAuth2** (aussi avec **JWT tokens**). Jetez un oeil au tutoriel [OAuth2 avec JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank}.
+* Clés d'API dans:
+ * Le header.
+ * Les paramètres de requêtes.
+ * Les cookies, etc.
+
+Plus toutes les fonctionnalités de sécurités venant de Starlette (incluant les **cookies de sessions**).
+
+Le tout conçu en composant réutilisable facilement intégrable à vos systèmes, data stores, base de données relationnelle ou NoSQL, etc.
+
+### Injection de dépendances
+
+FastAPI contient un système simple mais extrêmement puissant d'
Injection de Dépendances .
+
+* Même les dépendances peuvent avoir des dépendances, créant une hiérarchie ou un **"graph" de dépendances**
+* Tout est **automatiquement géré** par le framework
+* Toutes les dépendances peuvent éxiger des données d'une requêtes et **Augmenter les contraintes d'un path operation** et de la documentation automatique.
+* **Validation automatique** même pour les paramètres de *path operation* définis dans les dépendances.
+* Supporte les systèmes d'authentification d'utilisateurs complexes, les **connexions de base de données**, etc.
+* **Aucun compromis** avec les bases de données, les frontends, etc. Mais une intégration facile avec n'importe lequel d'entre eux.
+
+### "Plug-ins" illimités
+
+Ou, en d'autres termes, pas besoin d'eux, importez le code que vous voulez et utilisez le.
+
+Tout intégration est conçue pour être si simple à utiliser (avec des dépendances) que vous pouvez créer un "plug-in" pour votre application en deux lignes de code utilisant la même syntaxe que celle de vos *path operations*
+
+### Testé
+
+* 100%
de couverture de test .
+* 100%
d'annotations de type dans le code.
+* Utilisé dans des applications mises en production.
+
+## Fonctionnalités de Starlette
+
+**FastAPI** est complètement compatible (et basé sur)
Starlette . Le code utilisant Starlette que vous ajouterez fonctionnera donc aussi.
+
+En fait, `FastAPI` est un sous compposant de `Starlette`. Donc, si vous savez déjà comment utiliser Starlette, la plupart des fonctionnalités fonctionneront de la même manière.
+
+Avec **FastAPI** vous aurez toutes les fonctionnalités de **Starlette** (FastAPI est juste Starlette sous stéroïdes):
+
+* Des performances vraiments impressionnantes. C'est l'
un des framework Python les plus rapide, à égalité avec **NodeJS** et **GO** .
+* Le support des **WebSockets**.
+* Le support de **GraphQL**.
+* Les
tâches d'arrière-plan.
+* Des évènements de démarrages et d'arrêt.
+* Un client de test basé sur `request`
+* **CORS**, GZip, Static Files, Streaming responses.
+* Le support des **Sessions et Cookies**.
+* Une couverture de test à 100 %.
+* 100 % de la base de code avec des annotations de type.
+
+## Fonctionnalités de Pydantic
+
+**FastAPI** est totalement compatible avec (et basé sur)
Pydantic . Le code utilisant Pydantic que vous ajouterez fonctionnera donc aussi.
+
+Inclus des librairies externes basées, aussi, sur Pydantic, servent d'
ORM s,
ODM s pour les bases de données.
+
+Cela signifie aussi que, dans la plupart des cas, vous pouvez fournir l'objet reçu d'une requête **directement à la base de données**, comme tout est validé automatiquement.
+
+Inversément, dans la plupart des cas vous pourrez juste envoyer l'objet récupéré de la base de données **directement au client**
+
+Avec **FastAPI** vous aurez toutes les fonctionnalités de **Pydantic** (comme FastAPI est basé sur Pydantic pour toutes les manipulations de données):
+
+* **Pas de prise de tête**:
+ * Pas de nouveau langage de définition de schéma à apprendre.
+ * Si vous connaissez le typage en python vous savez comment utiliser Pydantic.
+* Aide votre **
IDE /
linter /cerveau**:
+ * Parce que les structures de données de pydantic consistent seulement en une instance de classe que vous définissez; l'auto-complétion, le linting, mypy et votre intuition devrait être largement suffisante pour valider vos données.
+* **Rapide**:
+ * Dans les
benchmarks Pydantic est plus rapide que toutes les autres librairies testées.
+* Valide les **structures complexes**:
+ * Utilise les modèles hiérarchique de Pydantic, le `typage` Python pour les `Lists`, `Dict`, etc.
+ * Et les validateurs permettent aux schémas de données complexes d'être clairement et facilement définis, validés et documentés sous forme d'un schéma JSON.
+ * Vous pouvez avoir des objets **JSON fortements imbriqués** tout en ayant, pour chacun, de la validation et des annotations.
+* **Renouvelable**:
+ * Pydantic permet de définir de nouveaux types de données ou vous pouvez étendre la validation avec des méthodes sur un modèle décoré avec le
décorateur de validation
+* 100% de couverture de test.
diff --git a/docs/fr/docs/tutorial/background-tasks.md b/docs/fr/docs/tutorial/background-tasks.md
new file mode 100644
index 000000000..06ef93cd7
--- /dev/null
+++ b/docs/fr/docs/tutorial/background-tasks.md
@@ -0,0 +1,94 @@
+# Tâches d'arrière-plan
+
+Vous pouvez définir des tâches d'arrière-plan qui seront exécutées après avoir retourné une réponse.
+
+Ceci est utile pour les opérations qui doivent avoir lieu après une requête, mais où le client n'a pas réellement besoin d'attendre que l'opération soit terminée pour recevoir une réponse.
+
+Cela comprend, par exemple :
+
+* Les notifications par email envoyées après l'exécution d'une action :
+ * Étant donné que se connecter à un serveur et envoyer un email a tendance à être «lent» (plusieurs secondes), vous pouvez retourner la réponse directement et envoyer la notification en arrière-plan.
+* Traiter des données :
+ * Par exemple, si vous recevez un fichier qui doit passer par un traitement lent, vous pouvez retourner une réponse «Accepted» (HTTP 202) puis faire le traitement en arrière-plan.
+
+
+## Utiliser `BackgroundTasks`
+
+Pour commencer, importez `BackgroundTasks` et définissez un paramètre dans votre *fonction de chemin* avec `BackgroundTasks` comme type déclaré.
+
+```Python hl_lines="1 13"
+{!../../../docs_src/background_tasks/tutorial001.py!}
+```
+
+**FastAPI** créera l'objet de type `BackgroundTasks` pour vous et le passera comme paramètre.
+
+## Créer une fonction de tâche
+
+Une fonction à exécuter comme tâche d'arrière-plan est juste une fonction standard qui peut recevoir des paramètres.
+
+Elle peut être une fonction asynchrone (`async def`) ou une fonction normale (`def`), **FastAPI** saura la gérer correctement.
+
+Dans cet exemple, la fonction de tâche écrira dans un fichier (afin de simuler un envoi d'email).
+
+L'opération d'écriture n'utilisant ni `async` ni `await`, on définit la fonction avec un `def` normal.
+
+```Python hl_lines="6-9"
+{!../../../docs_src/background_tasks/tutorial001.py!}
+```
+
+## Ajouter une tâche d'arrière-plan
+
+Dans votre *fonction de chemin*, passez votre fonction de tâche à l'objet de type `BackgroundTasks` (`background_tasks` ici) grâce à la méthode `.add_task()` :
+
+
+```Python hl_lines="14"
+{!../../../docs_src/background_tasks/tutorial001.py!}
+```
+
+`.add_task()` reçoit comme arguments :
+
+* Une fonction de tâche à exécuter en arrière-plan (`write_notification`).
+* Les arguments positionnels à passer à la fonction de tâche dans l'ordre (`email`).
+* Les arguments nommés à passer à la fonction de tâche (`message="some notification"`).
+
+## Injection de dépendances
+
+Utiliser `BackgroundTasks` fonctionne aussi avec le système d'injection de dépendances. Vous pouvez déclarer un paramètre de type `BackgroundTasks` à différents niveaux : dans une *fonction de chemin*, dans une dépendance, dans une sous-dépendance...
+
+**FastAPI** sait quoi faire dans chaque cas et comment réutiliser le même objet, afin que tous les paramètres de type `BackgroundTasks` soient fusionnés et que les tâches soient exécutées en arrière-plan :
+
+```Python hl_lines="13 15 22 25"
+{!../../../docs_src/background_tasks/tutorial002.py!}
+```
+
+Dans cet exemple, les messages seront écrits dans le fichier `log.txt` après que la réponse soit envoyée.
+
+S'il y avait une `query` (paramètre nommé `q`) dans la requête, alors elle sera écrite dans `log.txt` via une tâche d'arrière-plan.
+
+Et ensuite une autre tâche d'arrière-plan (générée dans les paramètres de la *la fonction de chemin*) écrira un message dans `log.txt` comprenant le paramètre de chemin `email`.
+
+## Détails techniques
+
+La classe `BackgroundTasks` provient directement de
`starlette.background` .
+
+Elle est importée/incluse directement dans **FastAPI** pour que vous puissiez l'importer depuis `fastapi` et éviter d'importer accidentellement `BackgroundTask` (sans `s` à la fin) depuis `starlette.background`.
+
+En utilisant seulement `BackgroundTasks` (et non `BackgroundTask`), il est possible de l'utiliser en tant que paramètre de *fonction de chemin* et de laisser **FastAPI** gérer le reste pour vous, comme en utilisant l'objet `Request` directement.
+
+Il est tout de même possible d'utiliser `BackgroundTask` seul dans **FastAPI**, mais dans ce cas il faut créer l'objet dans le code et renvoyer une `Response` Starlette l'incluant.
+
+Plus de détails sont disponibles dans
la documentation officielle de Starlette sur les tâches d'arrière-plan (via leurs classes `BackgroundTasks`et `BackgroundTask`).
+
+## Avertissement
+
+Si vous avez besoin de réaliser des traitements lourds en tâche d'arrière-plan et que vous n'avez pas besoin que ces traitements aient lieu dans le même process (par exemple, pas besoin de partager la mémoire, les variables, etc.), il peut s'avérer profitable d'utiliser des outils plus importants tels que
Celery .
+
+Ces outils nécessitent généralement des configurations plus complexes ainsi qu'un gestionnaire de queue de message, comme RabbitMQ ou Redis, mais ils permettent d'exécuter des tâches d'arrière-plan dans différents process, et potentiellement, sur plusieurs serveurs.
+
+Pour voir un exemple, allez voir les [Générateurs de projets](../project-generation.md){.internal-link target=_blank}, ils incluent tous Celery déjà configuré.
+
+Mais si vous avez besoin d'accéder aux variables et objets de la même application **FastAPI**, ou si vous avez besoin d'effectuer de petites tâches d'arrière-plan (comme envoyer des notifications par email), vous pouvez simplement vous contenter d'utiliser `BackgroundTasks`.
+
+## Résumé
+
+Importez et utilisez `BackgroundTasks` grâce aux paramètres de *fonction de chemin* et les dépendances pour ajouter des tâches d'arrière-plan.
diff --git a/docs/fr/mkdocs.yml b/docs/fr/mkdocs.yml
index 7c0b9b0c9..d9aac95f8 100644
--- a/docs/fr/mkdocs.yml
+++ b/docs/fr/mkdocs.yml
@@ -50,6 +50,10 @@ nav:
- tr: /tr/
- uk: /uk/
- zh: /zh/
+- features.md
+- fastapi-people.md
+- Tutoriel - Guide utilisateur:
+ - tutorial/background-tasks.md
markdown_extensions:
- toc:
permalink: true
diff --git a/docs/ko/docs/index.md b/docs/ko/docs/index.md
index abbad4fb4..71533f5eb 100644
--- a/docs/ko/docs/index.md
+++ b/docs/ko/docs/index.md
@@ -98,7 +98,7 @@ FastAPI는 현대적이고, 빠르며(고성능), 파이썬 표준 타입 힌트
-웹 API 대신 터미널에서 사용할
CLI 앱을 만들고 있다면,
**Typer** 를 확인해 보세요.
+웹 API 대신 터미널에서 사용할
CLI 앱을 만들고 있다면,
**Typer** 를 확인해 보십시오.
**Typer**는 FastAPI의 동생입니다. 그리고 **FastAPI의 CLI**가 되기 위해 생겼습니다. ⌨️ 🚀
@@ -139,7 +139,7 @@ $ pip install uvicorn[standard]
### 만들기
-* `main.py` 파일을 만드세요:
+* `main.py` 파일을 만드십시오:
```Python
from typing import Optional
@@ -162,7 +162,7 @@ def read_item(item_id: int, q: Optional[str] = None):
또는 async def
사용하기...
-여러분의 코드가 `async` / `await`을 사용한다면, `async def`를 사용하세요:
+여러분의 코드가 `async` / `await`을 사용한다면, `async def`를 사용하십시오.
```Python hl_lines="9 14"
from typing import Optional
@@ -184,7 +184,7 @@ async def read_item(item_id: int, q: Optional[str] = None):
**Note**:
-잘 모르겠다면, 문서에서 `async`와 `await` 에 관한 _"급하세요?"_ 섹션을 확인해 보세요.
+잘 모르겠다면, 문서에서 `async`와 `await` 에 관한 _"급하세요?"_ 섹션을 확인해 보십시오.
@@ -213,13 +213,13 @@ INFO: Application startup complete.
* `main`: `main.py` 파일 (파이썬 "모듈").
* `app`: the object created inside of `main.py` with the line `app = FastAPI()`.
-* `--reload`: 코드가 변경된 후 서버 재시작하기. 개발환경에서만 사용하세요.
+* `--reload`: 코드가 변경된 후 서버 재시작하기. 개발환경에서만 사용하십시오.
### 확인하기
-브라우저로
http://127.0.0.1:8000/items/5?q=somequery 를 열어보세요.
+브라우저로
http://127.0.0.1:8000/items/5?q=somequery 를 열어보십시오.
아래의 JSON 응답을 볼 수 있습니다:
@@ -244,13 +244,13 @@ INFO: Application startup complete.
### 대안 API 문서
-그리고 이제
http://127.0.0.1:8000/redoc 로 가보세요.
+그리고 이제
http://127.0.0.1:8000/redoc 로 가봅시다.
다른 자동 문서를 볼 수 있습니다(
ReDoc 제공):

-## 예제 개선
+## 예제 심화
이제 `PUT` 요청에 있는 본문(Body)을 받기 위해 `main.py`를 수정해봅시다.
@@ -314,7 +314,7 @@ def update_item(item_id: int, item: Item):
### 요약
-요약하면, 여러분은 매개변수의 타입, 본문 등을 함수 매개변수로써 **한번에** 선언했습니다.
+요약하면, 여러분은 매개변수의 타입, 본문 등을 함수 매개변수로서 **한번에** 선언했습니다.
여러분은 현대 표준 파이썬 타입으로 이를 행했습니다.
@@ -375,7 +375,7 @@ item: Item
* `price`을 필수 속성으로 갖고 `float` 형인지 검사.
* 만약 주어진다면, `is_offer`를 선택 속성으로 갖고 `bool` 형인지 검사.
* 이 모든 것은 깊이 중첩된 JSON 객체에도 적용됩니다.
-* JSON으로, 그리고 에서부터 자동 변환.
+* JSON을 변환하거나 JSON으로 변환하는 것을 자동화.
* 다음에서 사용할 수 있는 모든 것을 OpenAPI로 문서화:
* 대화형 문서 시스템.
* 여러 언어들에 대한 자동 클라이언트 코드 생성 시스템.
@@ -403,11 +403,11 @@ item: Item
... "item_price": item.price ...
```
-...그러고 나서 여러분의 편집기가 속성과 타입을 알고 자동 완성하는지 보세요:
+...그러고 나서 여러분의 편집기가 속성과 타입을 알고 자동 완성하는지 보십시오:

-더 많은 기능을 포함한 보다 완전한 예제의 경우,
튜토리얼 - 사용자 가이드 를 보세요.
+더 많은 기능을 포함한 보다 완전한 예제의 경우,
튜토리얼 - 사용자 가이드 를 보십시오.
**스포일러 주의**: 튜토리얼 - 사용자 가이드는:
@@ -428,9 +428,9 @@ item: Item
독립된 TechEmpower 벤치마크에서 Uvicorn에서 작동하는 FastAPI 어플리케이션이
사용 가능한 가장 빠른 프레임워크 중 하나 로 Starlette와 Uvicorn(FastAPI에서 내부적으로 사용)에만 밑돌고 있습니다. (*)
-자세한 내용은
벤치마크 섹션을 보세요.
+자세한 내용은
벤치마크 섹션을 보십시오.
-## 선택가능한 종속사항
+## 선택가능한 의존성
Pydantic이 사용하는:
diff --git a/docs/ko/docs/tutorial/path-params.md b/docs/ko/docs/tutorial/path-params.md
new file mode 100644
index 000000000..ede63f69d
--- /dev/null
+++ b/docs/ko/docs/tutorial/path-params.md
@@ -0,0 +1,244 @@
+# 경로 매개변수
+
+파이썬 포맷 문자열이 사용하는 동일한 문법으로 "매개변수" 또는 "변수"를 경로에 선언할 수 있습니다:
+
+```Python hl_lines="6-7"
+{!../../../docs_src/path_params/tutorial001.py!}
+```
+
+경로 매개변수 `item_id`의 값은 함수의 `item_id` 인자로 전달됩니다.
+
+그래서 이 예제를 실행하고
http://127.0.0.1:8000/items/foo 로 이동하면, 다음 응답을 볼 수 있습니다:
+
+```JSON
+{"item_id":"foo"}
+```
+
+## 타입이 있는 매개변수
+
+파이썬 표준 타입 어노테이션을 사용하여 함수에 있는 경로 매개변수의 타입을 선언할 수 있습니다:
+
+```Python hl_lines="7"
+{!../../../docs_src/path_params/tutorial002.py!}
+```
+
+지금과 같은 경우, `item_id`는 `int`로 선언 되었습니다.
+
+!!! check "확인"
+ 이 기능은 함수 내에서 오류 검사, 자동완성 등을 편집기를 지원합니다
+
+## 데이터
변환
+
+이 예제를 실행하고
http://127.0.0.1:8000/items/3 을 열면, 다음 응답을 볼 수 있습니다:
+
+```JSON
+{"item_id":3}
+```
+
+!!! check "확인"
+ 함수가 받은(반환도 하는) 값은 문자열 `"3"`이 아니라 파이썬 `int` 형인 `3`입니다.
+
+ 즉, 타입 선언을 하면 **FastAPI**는 자동으로 요청을
"파싱" 합니다.
+
+## 데이터 검증
+
+하지만 브라우저에서
http://127.0.0.1:8000/items/foo 로 이동하면, 멋진 HTTP 오류를 볼 수 있습니다:
+
+```JSON
+{
+ "detail": [
+ {
+ "loc": [
+ "path",
+ "item_id"
+ ],
+ "msg": "value is not a valid integer",
+ "type": "type_error.integer"
+ }
+ ]
+}
+```
+
+경로 매개변수 `item_id`는 `int`가 아닌 `"foo"` 값이기 때문입니다.
+
+`int` 대신 `float`을 전달하면 동일한 오류가 나타납니다:
http://127.0.0.1:8000/items/4.2
+
+!!! check "확인"
+ 즉, 파이썬 타입 선언을 하면 **FastAPI**는 데이터 검증을 합니다.
+
+ 오류는 검증을 통과하지 못한 지점도 정확하게 명시합니다.
+
+ 이는 API와 상호 작용하는 코드를 개발하고 디버깅하는 데 매우 유용합니다.
+
+## 문서화
+
+그리고 브라우저에서
http://127.0.0.1:8000/docs 를 열면, 다음과 같이 자동 대화식 API 문서를 볼 수 있습니다:
+
+
+
+!!! check "확인"
+ 다시 한번, 그저 파이썬 타입 선언을 하기만 하면 **FastAPI**는 자동 대화식 API 문서(Swagger UI 통합)를 제공합니다.
+
+ 경로 매개변수는 정수형으로 선언됐음을 주목하세요.
+
+## 표준 기반의 이점, 대체 문서화
+
+그리고 생성된 스키마는
OpenAPI 표준에서 나온 것이기 때문에 호환되는 도구가 많이 있습니다.
+
+이 덕분에 **FastAPI**는
http://127.0.0.1:8000/redoc 로 접속할 수 있는 (ReDoc을 사용하는) 대체 API 문서를 제공합니다:
+
+
+
+이와 마찬가지로 호환되는 도구가 많이 있습니다. 다양한 언어에 대한 코드 생성 도구를 포함합니다.
+
+## Pydantic
+
+모든 데이터 검증은
Pydantic 에 의해 내부적으로 수행되므로 이로 인한 모든 이점을 얻을 수 있습니다. 여러분은 관리를 잘 받고 있음을 느낄 수 있습니다.
+
+`str`, `float`, `bool`과 다른 복잡한 데이터 타입 선언을 할 수 있습니다.
+
+이 중 몇 가지는 자습서의 다음 장에서 살펴봅니다.
+
+## 순서 문제
+
+*경로 동작*을 만들때 고정 경로를 갖고 있는 상황들을 맞닦뜨릴 수 있습니다.
+
+`/users/me`처럼, 현재 사용자의 데이터를 가져온다고 합시다.
+
+사용자 ID를 이용해 특정 사용자의 정보를 가져오는 경로 `/users/{user_id}`도 있습니다.
+
+*경로 동작*은 순차적으로 평가되기 때문에 `/users/{user_id}` 이전에 `/users/me`를 먼저 선언해야 합니다:
+
+```Python hl_lines="6 11"
+{!../../../docs_src/path_params/tutorial003.py!}
+```
+
+그렇지 않으면 `/users/{user_id}`는 매개변수 `user_id`의 값을 `"me"`라고 "생각하여" `/users/me`도 연결합니다.
+
+## 사전정의 값
+
+만약 *경로 매개변수*를 받는 *경로 동작*이 있지만, 유효하고 미리 정의할 수 있는 *경로 매개변수* 값을 원한다면 파이썬 표준
`Enum` 을 사용할 수 있습니다.
+
+### `Enum` 클래스 생성
+
+`Enum`을 임포트하고 `str`과 `Enum`을 상속하는 서브 클래스를 만듭니다.
+
+`str`을 상속함으로써 API 문서는 값이 `string` 형이어야 하는 것을 알게 되고 제대로 렌더링 할 수 있게 됩니다.
+
+고정값으로 사용할 수 있는 유효한 클래스 어트리뷰트를 만듭니다:
+
+```Python hl_lines="1 6-9"
+{!../../../docs_src/path_params/tutorial005.py!}
+```
+
+!!! info "정보"
+
열거형(또는 enums) 은 파이썬 버전 3.4 이후로 사용가능합니다.
+
+!!! tip "팁"
+ 혹시 헷갈린다면, "AlexNet", "ResNet", 그리고 "LeNet"은 그저 기계 학습
모델 들의 이름입니다.
+
+### *경로 매개변수* 선언
+
+생성한 열거형 클래스(`ModelName`)를 사용하는 타입 어노테이션으로 *경로 매개변수*를 만듭니다:
+
+```Python hl_lines="16"
+{!../../../docs_src/path_params/tutorial005.py!}
+```
+
+### 문서 확인
+
+*경로 매개변수*에 사용할 수 있는 값은 미리 정의되어 있으므로 대화형 문서에서 멋지게 표시됩니다:
+
+
+
+### 파이썬 *열거형*으로 작업하기
+
+*경로 매개변수*의 값은 *열거형 멤버*가 됩니다.
+
+#### *열거형 멤버* 비교
+
+열거체 `ModelName`의 *열거형 멤버*를 비교할 수 있습니다:
+
+```Python hl_lines="17"
+{!../../../docs_src/path_params/tutorial005.py!}
+```
+
+#### *열거형 값* 가져오기
+
+`model_name.value` 또는 일반적으로 `your_enum_member.value`를 이용하여 실제값(지금의 경우 `str`)을 가져올 수 있습니다:
+
+```Python hl_lines="20"
+{!../../../docs_src/path_params/tutorial005.py!}
+```
+
+!!! tip "팁"
+ `ModelName.lenet.value`로도 값 `"lenet"`에 접근할 수 있습니다.
+
+#### *열거형 멤버* 반환
+
+*경로 동작*에서 중첩 JSON 본문(예: `dict`) 역시 *열거형 멤버*를 반환할 수 있습니다.
+
+클라이언트에 반환하기 전에 해당 값(이 경우 문자열)으로 변환됩니다:
+
+```Python hl_lines="18 21 23"
+{!../../../docs_src/path_params/tutorial005.py!}
+```
+
+클라이언트는 아래의 JSON 응답을 얻습니다:
+
+```JSON
+{
+ "model_name": "alexnet",
+ "message": "Deep Learning FTW!"
+}
+```
+
+## 경로를 포함하는 경로 매개변수
+
+`/files/{file_path}`가 있는 *경로 동작*이 있다고 해봅시다.
+
+그런데 여러분은 `home/johndoe/myfile.txt`처럼 *path*에 들어있는 `file_path` 자체가 필요합니다.
+
+따라서 해당 파일의 URL은 다음처럼 됩니다: `/files/home/johndoe/myfile.txt`.
+
+### OpenAPI 지원
+
+테스트와 정의가 어려운 시나리오로 이어질 수 있으므로 OpenAPI는 *경로*를 포함하는 *경로 매개변수*를 내부에 선언하는 방법을 지원하지 않습니다.
+
+그럼에도 Starlette의 내부 도구중 하나를 사용하여 **FastAPI**에서는 할 수 있습니다.
+
+매개변수에 경로가 포함되어야 한다는 문서를 추가하지 않아도 문서는 계속 작동합니다.
+
+### 경로 변환기
+
+Starlette에서 직접 옵션을 사용하면 다음과 같은 URL을 사용하여 *path*를 포함하는 *경로 매개변수*를 선언 할 수 있습니다:
+
+```
+/files/{file_path:path}
+```
+
+이러한 경우 매개변수의 이름은 `file_path`이고 마지막 부분 `:path`는 매개변수가 *경로*와 일치해야함을 알려줍니다.
+
+그러므로 다음과 같이 사용할 수 있습니다:
+
+```Python hl_lines="6"
+{!../../../docs_src/path_params/tutorial004.py!}
+```
+
+!!! tip "팁"
+ 매개변수가 `/home/johndoe/myfile.txt`를 갖고 있어 슬래시로 시작(`/`)해야 할 수 있습니다.
+
+ 이 경우 URL은: `/files//home/johndoe/myfile.txt`이며 `files`과 `home` 사이에 이중 슬래시(`//`)가 생깁니다.
+
+## 요약
+
+**FastAPI**과 함께라면 짧고 직관적인 표준 파이썬 타입 선언을 사용하여 다음을 얻을 수 있습니다:
+
+* 편집기 지원: 오류 검사, 자동완성 등
+* 데이터 "
파싱 "
+* 데이터 검증
+* API 주석(Annotation)과 자동 문서
+
+위 사항들을 그저 한번에 선언하면 됩니다.
+
+이는 (원래 성능과는 별개로) 대체 프레임워크와 비교했을 때 **FastAPI**의 주요 가시적 장점일 것입니다.
\ No newline at end of file
diff --git a/docs/ko/docs/tutorial/query-params.md b/docs/ko/docs/tutorial/query-params.md
new file mode 100644
index 000000000..05f2ff9c9
--- /dev/null
+++ b/docs/ko/docs/tutorial/query-params.md
@@ -0,0 +1,198 @@
+# 쿼리 매개변수
+
+경로 매개변수의 일부가 아닌 다른 함수 매개변수를 선언할 때, "쿼리" 매개변수로 자동 해석합니다.
+
+```Python hl_lines="9"
+{!../../../docs_src/query_params/tutorial001.py!}
+```
+
+쿼리는 URL에서 `?` 후에 나오고 `&`으로 구분되는 키-값 쌍의 집합입니다.
+
+예를 들어, URL에서:
+
+```
+http://127.0.0.1:8000/items/?skip=0&limit=10
+```
+
+...쿼리 매개변수는:
+
+* `skip`: 값 `0`을 가집니다.
+* `limit`: 값 `10`을 가집니다.
+
+URL의 일부이므로 "자연스럽게" 문자열입니다.
+
+하지만 파이썬 타입과 함께 선언할 경우(위 예에서 `int`), 해당 타입으로 변환되고 이에 대해 검증합니다.
+
+경로 매개변수에 적용된 동일한 프로세스가 쿼리 매개변수에도 적용됩니다:
+
+* (당연히) 편집기 지원
+* 데이터
"파싱"
+* 데이터 검증
+* 자동 문서화
+
+## 기본값
+
+쿼리 매개변수는 경로에서 고정된 부분이 아니기 때문에 선택적일 수 있고 기본값을 가질 수 있습니다.
+
+위 예에서 `skip=0`과 `limit=10`은 기본값을 갖고 있습니다.
+
+그러므로 URL로 이동하면:
+
+```
+http://127.0.0.1:8000/items/
+```
+
+아래로 이동한 것과 같습니다:
+
+```
+http://127.0.0.1:8000/items/?skip=0&limit=10
+```
+
+하지만 가령 아래로 이동한 경우:
+
+```
+http://127.0.0.1:8000/items/?skip=20
+```
+
+함수의 매개변수 값은 아래가 됩니다:
+
+* `skip=20`: URL에서 지정했기 때문입니다
+* `limit=10`: 기본값이기 때문입니다
+
+## 선택적 매개변수
+
+같은 방법으로 기본값을 `None`으로 설정하여 선택적 매개변수를 선언할 수 있습니다:
+
+```Python hl_lines="9"
+{!../../../docs_src/query_params/tutorial002.py!}
+```
+
+이 경우 함수 매개변수 `q`는 선택적이며 기본값으로 `None` 값이 됩니다.
+
+!!! check "확인"
+ **FastAPI**는 `item_id`가 경로 매개변수이고 `q`는 경로 매개변수가 아닌 쿼리 매개변수라는 것을 알 정도로 충분히 똑똑합니다.
+
+!!! note "참고"
+ FastAPI는 `q`가 `= None`이므로 선택적이라는 것을 인지합니다.
+
+ `Optional[str]`에 있는 `Optional`은 FastAPI(FastAPI는 `str` 부분만 사용합니다)가 사용하는게 아니지만, `Optional[str]`은 편집기에게 코드에서 오류를 찾아낼 수 있게 도와줍니다.
+
+## 쿼리 매개변수 형변환
+
+`bool` 형으로 선언할 수도 있고, 아래처럼 변환됩니다:
+
+```Python hl_lines="9"
+{!../../../docs_src/query_params/tutorial003.py!}
+```
+
+이 경우, 아래로 이동하면:
+
+```
+http://127.0.0.1:8000/items/foo?short=1
+```
+
+또는
+
+```
+http://127.0.0.1:8000/items/foo?short=True
+```
+
+또는
+
+```
+http://127.0.0.1:8000/items/foo?short=true
+```
+
+또는
+
+```
+http://127.0.0.1:8000/items/foo?short=on
+```
+
+또는
+
+```
+http://127.0.0.1:8000/items/foo?short=yes
+```
+
+또는 다른 어떤 변형(대문자, 첫글자만 대문자 등)이더라도 함수는 매개변수 `bool`형을 가진 `short`의 값이 `True`임을 압니다. 그렇지 않은 경우 `False`입니다.
+
+
+## 여러 경로/쿼리 매개변수
+
+여러 경로 매개변수와 쿼리 매개변수를 동시에 선언할 수 있으며 **FastAPI**는 어느 것이 무엇인지 알고 있습니다.
+
+그리고 특정 순서로 선언할 필요가 없습니다.
+
+매개변수들은 이름으로 감지됩니다:
+
+```Python hl_lines="8 10"
+{!../../../docs_src/query_params/tutorial004.py!}
+```
+
+## 필수 쿼리 매개변수
+
+경로가 아닌 매개변수에 대한 기본값을 선언할 때(지금은 쿼리 매개변수만 보았습니다), 해당 매개변수는 필수적(Required)이지 않았습니다.
+
+특정값을 추가하지 않고 선택적으로 만들기 위해선 기본값을 `None`으로 설정하면 됩니다.
+
+그러나 쿼리 매개변수를 필수로 만들려면 기본값을 선언할 수 없습니다:
+
+```Python hl_lines="6-7"
+{!../../../docs_src/query_params/tutorial005.py!}
+```
+
+여기 쿼리 매개변수 `needy`는 `str`형인 필수 쿼리 매개변수입니다.
+
+브라우저에서 URL을 아래처럼 연다면:
+
+```
+http://127.0.0.1:8000/items/foo-item
+```
+
+...필수 매개변수 `needy`를 넣지 않았기 때문에 아래와 같은 오류를 보게 됩니다:
+
+```JSON
+{
+ "detail": [
+ {
+ "loc": [
+ "query",
+ "needy"
+ ],
+ "msg": "field required",
+ "type": "value_error.missing"
+ }
+ ]
+}
+```
+
+`needy`는 필수 매개변수이므로 URL에 반드시 설정해줘야 합니다:
+
+```
+http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
+```
+
+...아래처럼 작동합니다:
+
+```JSON
+{
+ "item_id": "foo-item",
+ "needy": "sooooneedy"
+}
+```
+
+그리고 물론, 일부 매개변수는 필수로, 다른 일부는 기본값을, 또 다른 일부는 선택적으로 선언할 수 있습니다:
+
+```Python hl_lines="10"
+{!../../../docs_src/query_params/tutorial006.py!}
+```
+
+이 경우 3가지 쿼리 매개변수가 있습니다:
+
+* `needy`, 필수적인 `str`.
+* `skip`, 기본값이 `0`인 `int`.
+* `limit`, 선택적인 `int`.
+
+!!! tip "팁"
+ [경로 매개변수](path-params.md#predefined-values){.internal-link target=_blank}와 마찬가지로 `Enum`을 사용할 수 있습니다.
diff --git a/docs/ko/mkdocs.yml b/docs/ko/mkdocs.yml
index 360d18297..f5ae4b439 100644
--- a/docs/ko/mkdocs.yml
+++ b/docs/ko/mkdocs.yml
@@ -53,6 +53,8 @@ nav:
- 자습서 - 사용자 안내서:
- tutorial/index.md
- tutorial/first-steps.md
+ - tutorial/path-params.md
+ - tutorial/query-params.md
- tutorial/header-params.md
markdown_extensions:
- toc:
diff --git a/docs/zh/docs/tutorial/query-params.md b/docs/zh/docs/tutorial/query-params.md
index 36f17beb9..b1668a2d2 100644
--- a/docs/zh/docs/tutorial/query-params.md
+++ b/docs/zh/docs/tutorial/query-params.md
@@ -191,36 +191,3 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
!!! tip
你还可以像在 [路径参数](path-params.md#predefined-values){.internal-link target=_blank} 中那样使用 `Enum`。
-
-## Optional 类型声明
-
-!!! warning
- 这可能是一个比较高级的使用场景。
-
- 您也可以跳过它。
-
-如果你正在使用 `mypy`,它可能会对如下的类型声明进行警告:
-
-```Python
-limit: int = None
-```
-
-提示类似以下错误:
-
-```
-Incompatible types in assignment (expression has type "None", variable has type "int")
-```
-
-在这种情况下,你可以使用 `Optional` 来告诉 `mypy` 该值可以为 `None`,例如:
-
-```Python
-from typing import Optional
-
-limit: Optional[int] = None
-```
-
-在一个*路径操作*中,看起来会是:
-
-```Python hl_lines="9"
-{!../../../docs_src/query_params/tutorial007.py!}
-```
diff --git a/docs_src/schema_extra_example/tutorial004.py b/docs_src/schema_extra_example/tutorial004.py
new file mode 100644
index 000000000..9f0e8b437
--- /dev/null
+++ b/docs_src/schema_extra_example/tutorial004.py
@@ -0,0 +1,52 @@
+from typing import Optional
+
+from fastapi import Body, FastAPI
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+ name: str
+ description: Optional[str] = None
+ price: float
+ tax: Optional[float] = None
+
+
+@app.put("/items/{item_id}")
+async def update_item(
+ *,
+ item_id: int,
+ item: Item = Body(
+ ...,
+ examples={
+ "normal": {
+ "summary": "A normal example",
+ "description": "A **normal** item works correctly.",
+ "value": {
+ "name": "Foo",
+ "description": "A very nice Item",
+ "price": 35.4,
+ "tax": 3.2,
+ },
+ },
+ "converted": {
+ "summary": "An example with converted data",
+ "description": "FastAPI can convert price `strings` to actual `numbers` automatically",
+ "value": {
+ "name": "Bar",
+ "price": "35.4",
+ },
+ },
+ "invalid": {
+ "summary": "Invalid data is rejected with an error",
+ "value": {
+ "name": "Baz",
+ "price": "thirty five point four",
+ },
+ },
+ },
+ ),
+):
+ results = {"item_id": item_id, "item": item}
+ return results
diff --git a/fastapi/__init__.py b/fastapi/__init__.py
index c0bb0e451..332c5aaf7 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.63.0"
+__version__ = "0.64.0"
from starlette import status as status
diff --git a/fastapi/openapi/utils.py b/fastapi/openapi/utils.py
index 410ba9389..6f749ef9c 100644
--- a/fastapi/openapi/utils.py
+++ b/fastapi/openapi/utils.py
@@ -21,7 +21,7 @@ from fastapi.utils import (
get_model_definitions,
)
from pydantic import BaseModel
-from pydantic.fields import ModelField
+from pydantic.fields import ModelField, Undefined
from pydantic.schema import (
field_schema,
get_flat_models_from_fields,
@@ -101,6 +101,10 @@ def get_openapi_operation_parameters(
}
if field_info.description:
parameter["description"] = field_info.description
+ if field_info.examples:
+ parameter["examples"] = jsonable_encoder(field_info.examples)
+ elif field_info.example != Undefined:
+ parameter["example"] = jsonable_encoder(field_info.example)
if field_info.deprecated:
parameter["deprecated"] = field_info.deprecated
parameters.append(parameter)
@@ -124,7 +128,12 @@ def get_openapi_operation_request_body(
request_body_oai: Dict[str, Any] = {}
if required:
request_body_oai["required"] = required
- request_body_oai["content"] = {request_media_type: {"schema": body_schema}}
+ request_media_content: Dict[str, Any] = {"schema": body_schema}
+ if field_info.examples:
+ request_media_content["examples"] = jsonable_encoder(field_info.examples)
+ elif field_info.example != Undefined:
+ request_media_content["example"] = jsonable_encoder(field_info.example)
+ request_body_oai["content"] = {request_media_type: request_media_content}
return request_body_oai
diff --git a/fastapi/param_functions.py b/fastapi/param_functions.py
index 9ebb59100..ff65d7271 100644
--- a/fastapi/param_functions.py
+++ b/fastapi/param_functions.py
@@ -1,6 +1,7 @@
-from typing import Any, Callable, Optional, Sequence
+from typing import Any, Callable, Dict, Optional, Sequence
from fastapi import params
+from pydantic.fields import Undefined
def Path( # noqa: N802
@@ -16,6 +17,8 @@ def Path( # noqa: N802
min_length: Optional[int] = None,
max_length: Optional[int] = None,
regex: Optional[str] = None,
+ example: Any = Undefined,
+ examples: Optional[Dict[str, Any]] = None,
deprecated: Optional[bool] = None,
**extra: Any,
) -> Any:
@@ -31,6 +34,8 @@ def Path( # noqa: N802
min_length=min_length,
max_length=max_length,
regex=regex,
+ example=example,
+ examples=examples,
deprecated=deprecated,
**extra,
)
@@ -49,6 +54,8 @@ def Query( # noqa: N802
min_length: Optional[int] = None,
max_length: Optional[int] = None,
regex: Optional[str] = None,
+ example: Any = Undefined,
+ examples: Optional[Dict[str, Any]] = None,
deprecated: Optional[bool] = None,
**extra: Any,
) -> Any:
@@ -64,6 +71,8 @@ def Query( # noqa: N802
min_length=min_length,
max_length=max_length,
regex=regex,
+ example=example,
+ examples=examples,
deprecated=deprecated,
**extra,
)
@@ -83,6 +92,8 @@ def Header( # noqa: N802
min_length: Optional[int] = None,
max_length: Optional[int] = None,
regex: Optional[str] = None,
+ example: Any = Undefined,
+ examples: Optional[Dict[str, Any]] = None,
deprecated: Optional[bool] = None,
**extra: Any,
) -> Any:
@@ -99,6 +110,8 @@ def Header( # noqa: N802
min_length=min_length,
max_length=max_length,
regex=regex,
+ example=example,
+ examples=examples,
deprecated=deprecated,
**extra,
)
@@ -117,6 +130,8 @@ def Cookie( # noqa: N802
min_length: Optional[int] = None,
max_length: Optional[int] = None,
regex: Optional[str] = None,
+ example: Any = Undefined,
+ examples: Optional[Dict[str, Any]] = None,
deprecated: Optional[bool] = None,
**extra: Any,
) -> Any:
@@ -132,6 +147,8 @@ def Cookie( # noqa: N802
min_length=min_length,
max_length=max_length,
regex=regex,
+ example=example,
+ examples=examples,
deprecated=deprecated,
**extra,
)
@@ -152,6 +169,8 @@ def Body( # noqa: N802
min_length: Optional[int] = None,
max_length: Optional[int] = None,
regex: Optional[str] = None,
+ example: Any = Undefined,
+ examples: Optional[Dict[str, Any]] = None,
**extra: Any,
) -> Any:
return params.Body(
@@ -168,6 +187,8 @@ def Body( # noqa: N802
min_length=min_length,
max_length=max_length,
regex=regex,
+ example=example,
+ examples=examples,
**extra,
)
@@ -186,6 +207,8 @@ def Form( # noqa: N802
min_length: Optional[int] = None,
max_length: Optional[int] = None,
regex: Optional[str] = None,
+ example: Any = Undefined,
+ examples: Optional[Dict[str, Any]] = None,
**extra: Any,
) -> Any:
return params.Form(
@@ -201,6 +224,8 @@ def Form( # noqa: N802
min_length=min_length,
max_length=max_length,
regex=regex,
+ example=example,
+ examples=examples,
**extra,
)
@@ -219,6 +244,8 @@ def File( # noqa: N802
min_length: Optional[int] = None,
max_length: Optional[int] = None,
regex: Optional[str] = None,
+ example: Any = Undefined,
+ examples: Optional[Dict[str, Any]] = None,
**extra: Any,
) -> Any:
return params.File(
@@ -234,6 +261,8 @@ def File( # noqa: N802
min_length=min_length,
max_length=max_length,
regex=regex,
+ example=example,
+ examples=examples,
**extra,
)
diff --git a/fastapi/params.py b/fastapi/params.py
index aa3269a80..3cab98b78 100644
--- a/fastapi/params.py
+++ b/fastapi/params.py
@@ -1,7 +1,7 @@
from enum import Enum
-from typing import Any, Callable, Optional, Sequence
+from typing import Any, Callable, Dict, Optional, Sequence
-from pydantic.fields import FieldInfo
+from pydantic.fields import FieldInfo, Undefined
class ParamTypes(Enum):
@@ -28,10 +28,14 @@ class Param(FieldInfo):
min_length: Optional[int] = None,
max_length: Optional[int] = None,
regex: Optional[str] = None,
+ example: Any = Undefined,
+ examples: Optional[Dict[str, Any]] = None,
deprecated: Optional[bool] = None,
**extra: Any,
):
self.deprecated = deprecated
+ self.example = example
+ self.examples = examples
super().__init__(
default,
alias=alias,
@@ -68,6 +72,8 @@ class Path(Param):
min_length: Optional[int] = None,
max_length: Optional[int] = None,
regex: Optional[str] = None,
+ example: Any = Undefined,
+ examples: Optional[Dict[str, Any]] = None,
deprecated: Optional[bool] = None,
**extra: Any,
):
@@ -85,6 +91,8 @@ class Path(Param):
max_length=max_length,
regex=regex,
deprecated=deprecated,
+ example=example,
+ examples=examples,
**extra,
)
@@ -106,6 +114,8 @@ class Query(Param):
min_length: Optional[int] = None,
max_length: Optional[int] = None,
regex: Optional[str] = None,
+ example: Any = Undefined,
+ examples: Optional[Dict[str, Any]] = None,
deprecated: Optional[bool] = None,
**extra: Any,
):
@@ -122,6 +132,8 @@ class Query(Param):
max_length=max_length,
regex=regex,
deprecated=deprecated,
+ example=example,
+ examples=examples,
**extra,
)
@@ -144,6 +156,8 @@ class Header(Param):
min_length: Optional[int] = None,
max_length: Optional[int] = None,
regex: Optional[str] = None,
+ example: Any = Undefined,
+ examples: Optional[Dict[str, Any]] = None,
deprecated: Optional[bool] = None,
**extra: Any,
):
@@ -161,6 +175,8 @@ class Header(Param):
max_length=max_length,
regex=regex,
deprecated=deprecated,
+ example=example,
+ examples=examples,
**extra,
)
@@ -182,6 +198,8 @@ class Cookie(Param):
min_length: Optional[int] = None,
max_length: Optional[int] = None,
regex: Optional[str] = None,
+ example: Any = Undefined,
+ examples: Optional[Dict[str, Any]] = None,
deprecated: Optional[bool] = None,
**extra: Any,
):
@@ -198,6 +216,8 @@ class Cookie(Param):
max_length=max_length,
regex=regex,
deprecated=deprecated,
+ example=example,
+ examples=examples,
**extra,
)
@@ -219,10 +239,14 @@ class Body(FieldInfo):
min_length: Optional[int] = None,
max_length: Optional[int] = None,
regex: Optional[str] = None,
+ example: Any = Undefined,
+ examples: Optional[Dict[str, Any]] = None,
**extra: Any,
):
self.embed = embed
self.media_type = media_type
+ self.example = example
+ self.examples = examples
super().__init__(
default,
alias=alias,
@@ -258,6 +282,8 @@ class Form(Body):
min_length: Optional[int] = None,
max_length: Optional[int] = None,
regex: Optional[str] = None,
+ example: Any = Undefined,
+ examples: Optional[Dict[str, Any]] = None,
**extra: Any,
):
super().__init__(
@@ -274,6 +300,8 @@ class Form(Body):
min_length=min_length,
max_length=max_length,
regex=regex,
+ example=example,
+ examples=examples,
**extra,
)
@@ -294,6 +322,8 @@ class File(Form):
min_length: Optional[int] = None,
max_length: Optional[int] = None,
regex: Optional[str] = None,
+ example: Any = Undefined,
+ examples: Optional[Dict[str, Any]] = None,
**extra: Any,
):
super().__init__(
@@ -309,6 +339,8 @@ class File(Form):
min_length=min_length,
max_length=max_length,
regex=regex,
+ example=example,
+ examples=examples,
**extra,
)
diff --git a/scripts/docs.py b/scripts/docs.py
index b206e9157..ec3ad76e6 100644
--- a/scripts/docs.py
+++ b/scripts/docs.py
@@ -206,6 +206,9 @@ index_sponsors_template = """
{% if sponsors %}
{% for sponsor in sponsors.gold -%}
+{% endfor -%}
+{%- for sponsor in sponsors.silver -%}
+
{% endfor %}
{% endif %}
"""
diff --git a/tests/test_schema_extra_examples.py b/tests/test_schema_extra_examples.py
new file mode 100644
index 000000000..3e0d846cd
--- /dev/null
+++ b/tests/test_schema_extra_examples.py
@@ -0,0 +1,889 @@
+from fastapi import Body, Cookie, FastAPI, Header, Path, Query
+from fastapi.testclient import TestClient
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+ data: str
+
+ class Config:
+ schema_extra = {"example": {"data": "Data in schema_extra"}}
+
+
+@app.post("/schema_extra/")
+def schema_extra(item: Item):
+ return item
+
+
+@app.post("/example/")
+def example(item: Item = Body(..., example={"data": "Data in Body example"})):
+ return item
+
+
+@app.post("/examples/")
+def examples(
+ item: Item = Body(
+ ...,
+ examples={
+ "example1": {
+ "summary": "example1 summary",
+ "value": {"data": "Data in Body examples, example1"},
+ },
+ "example2": {"value": {"data": "Data in Body examples, example2"}},
+ },
+ )
+):
+ return item
+
+
+@app.post("/example_examples/")
+def example_examples(
+ item: Item = Body(
+ ...,
+ example={"data": "Overriden example"},
+ examples={
+ "example1": {"value": {"data": "examples example_examples 1"}},
+ "example2": {"value": {"data": "examples example_examples 2"}},
+ },
+ )
+):
+ return item
+
+
+# TODO: enable these tests once/if Form(embed=False) is supported
+# TODO: In that case, define if File() should support example/examples too
+# @app.post("/form_example")
+# def form_example(firstname: str = Form(..., example="John")):
+# return firstname
+
+
+# @app.post("/form_examples")
+# def form_examples(
+# lastname: str = Form(
+# ...,
+# examples={
+# "example1": {"summary": "last name summary", "value": "Doe"},
+# "example2": {"value": "Doesn't"},
+# },
+# ),
+# ):
+# return lastname
+
+
+# @app.post("/form_example_examples")
+# def form_example_examples(
+# lastname: str = Form(
+# ...,
+# example="Doe overriden",
+# examples={
+# "example1": {"summary": "last name summary", "value": "Doe"},
+# "example2": {"value": "Doesn't"},
+# },
+# ),
+# ):
+# return lastname
+
+
+@app.get("/path_example/{item_id}")
+def path_example(
+ item_id: str = Path(
+ ...,
+ example="item_1",
+ ),
+):
+ return item_id
+
+
+@app.get("/path_examples/{item_id}")
+def path_examples(
+ item_id: str = Path(
+ ...,
+ examples={
+ "example1": {"summary": "item ID summary", "value": "item_1"},
+ "example2": {"value": "item_2"},
+ },
+ ),
+):
+ return item_id
+
+
+@app.get("/path_example_examples/{item_id}")
+def path_example_examples(
+ item_id: str = Path(
+ ...,
+ example="item_overriden",
+ examples={
+ "example1": {"summary": "item ID summary", "value": "item_1"},
+ "example2": {"value": "item_2"},
+ },
+ ),
+):
+ return item_id
+
+
+@app.get("/query_example/")
+def query_example(
+ data: str = Query(
+ None,
+ example="query1",
+ ),
+):
+ return data
+
+
+@app.get("/query_examples/")
+def query_examples(
+ data: str = Query(
+ None,
+ examples={
+ "example1": {"summary": "Query example 1", "value": "query1"},
+ "example2": {"value": "query2"},
+ },
+ ),
+):
+ return data
+
+
+@app.get("/query_example_examples/")
+def query_example_examples(
+ data: str = Query(
+ None,
+ example="query_overriden",
+ examples={
+ "example1": {"summary": "Qeury example 1", "value": "query1"},
+ "example2": {"value": "query2"},
+ },
+ ),
+):
+ return data
+
+
+@app.get("/header_example/")
+def header_example(
+ data: str = Header(
+ None,
+ example="header1",
+ ),
+):
+ return data
+
+
+@app.get("/header_examples/")
+def header_examples(
+ data: str = Header(
+ None,
+ examples={
+ "example1": {"summary": "header example 1", "value": "header1"},
+ "example2": {"value": "header2"},
+ },
+ ),
+):
+ return data
+
+
+@app.get("/header_example_examples/")
+def header_example_examples(
+ data: str = Header(
+ None,
+ example="header_overriden",
+ examples={
+ "example1": {"summary": "Qeury example 1", "value": "header1"},
+ "example2": {"value": "header2"},
+ },
+ ),
+):
+ return data
+
+
+@app.get("/cookie_example/")
+def cookie_example(
+ data: str = Cookie(
+ None,
+ example="cookie1",
+ ),
+):
+ return data
+
+
+@app.get("/cookie_examples/")
+def cookie_examples(
+ data: str = Cookie(
+ None,
+ examples={
+ "example1": {"summary": "cookie example 1", "value": "cookie1"},
+ "example2": {"value": "cookie2"},
+ },
+ ),
+):
+ return data
+
+
+@app.get("/cookie_example_examples/")
+def cookie_example_examples(
+ data: str = Cookie(
+ None,
+ example="cookie_overriden",
+ examples={
+ "example1": {"summary": "Qeury example 1", "value": "cookie1"},
+ "example2": {"value": "cookie2"},
+ },
+ ),
+):
+ return data
+
+
+client = TestClient(app)
+
+
+openapi_schema = {
+ "openapi": "3.0.2",
+ "info": {"title": "FastAPI", "version": "0.1.0"},
+ "paths": {
+ "/schema_extra/": {
+ "post": {
+ "summary": "Schema Extra",
+ "operationId": "schema_extra_schema_extra__post",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {"$ref": "#/components/schemas/Item"}
+ }
+ },
+ "required": True,
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ },
+ "/example/": {
+ "post": {
+ "summary": "Example",
+ "operationId": "example_example__post",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {"$ref": "#/components/schemas/Item"},
+ "example": {"data": "Data in Body example"},
+ }
+ },
+ "required": True,
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ },
+ "/examples/": {
+ "post": {
+ "summary": "Examples",
+ "operationId": "examples_examples__post",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {"$ref": "#/components/schemas/Item"},
+ "examples": {
+ "example1": {
+ "summary": "example1 summary",
+ "value": {
+ "data": "Data in Body examples, example1"
+ },
+ },
+ "example2": {
+ "value": {"data": "Data in Body examples, example2"}
+ },
+ },
+ }
+ },
+ "required": True,
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ },
+ "/example_examples/": {
+ "post": {
+ "summary": "Example Examples",
+ "operationId": "example_examples_example_examples__post",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {"$ref": "#/components/schemas/Item"},
+ "examples": {
+ "example1": {
+ "value": {"data": "examples example_examples 1"}
+ },
+ "example2": {
+ "value": {"data": "examples example_examples 2"}
+ },
+ },
+ }
+ },
+ "required": True,
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ },
+ "/path_example/{item_id}": {
+ "get": {
+ "summary": "Path Example",
+ "operationId": "path_example_path_example__item_id__get",
+ "parameters": [
+ {
+ "required": True,
+ "schema": {"title": "Item Id", "type": "string"},
+ "example": "item_1",
+ "name": "item_id",
+ "in": "path",
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ },
+ "/path_examples/{item_id}": {
+ "get": {
+ "summary": "Path Examples",
+ "operationId": "path_examples_path_examples__item_id__get",
+ "parameters": [
+ {
+ "required": True,
+ "schema": {"title": "Item Id", "type": "string"},
+ "examples": {
+ "example1": {
+ "summary": "item ID summary",
+ "value": "item_1",
+ },
+ "example2": {"value": "item_2"},
+ },
+ "name": "item_id",
+ "in": "path",
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ },
+ "/path_example_examples/{item_id}": {
+ "get": {
+ "summary": "Path Example Examples",
+ "operationId": "path_example_examples_path_example_examples__item_id__get",
+ "parameters": [
+ {
+ "required": True,
+ "schema": {"title": "Item Id", "type": "string"},
+ "examples": {
+ "example1": {
+ "summary": "item ID summary",
+ "value": "item_1",
+ },
+ "example2": {"value": "item_2"},
+ },
+ "name": "item_id",
+ "in": "path",
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ },
+ "/query_example/": {
+ "get": {
+ "summary": "Query Example",
+ "operationId": "query_example_query_example__get",
+ "parameters": [
+ {
+ "required": False,
+ "schema": {"title": "Data", "type": "string"},
+ "example": "query1",
+ "name": "data",
+ "in": "query",
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ },
+ "/query_examples/": {
+ "get": {
+ "summary": "Query Examples",
+ "operationId": "query_examples_query_examples__get",
+ "parameters": [
+ {
+ "required": False,
+ "schema": {"title": "Data", "type": "string"},
+ "examples": {
+ "example1": {
+ "summary": "Query example 1",
+ "value": "query1",
+ },
+ "example2": {"value": "query2"},
+ },
+ "name": "data",
+ "in": "query",
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ },
+ "/query_example_examples/": {
+ "get": {
+ "summary": "Query Example Examples",
+ "operationId": "query_example_examples_query_example_examples__get",
+ "parameters": [
+ {
+ "required": False,
+ "schema": {"title": "Data", "type": "string"},
+ "examples": {
+ "example1": {
+ "summary": "Qeury example 1",
+ "value": "query1",
+ },
+ "example2": {"value": "query2"},
+ },
+ "name": "data",
+ "in": "query",
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ },
+ "/header_example/": {
+ "get": {
+ "summary": "Header Example",
+ "operationId": "header_example_header_example__get",
+ "parameters": [
+ {
+ "required": False,
+ "schema": {"title": "Data", "type": "string"},
+ "example": "header1",
+ "name": "data",
+ "in": "header",
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ },
+ "/header_examples/": {
+ "get": {
+ "summary": "Header Examples",
+ "operationId": "header_examples_header_examples__get",
+ "parameters": [
+ {
+ "required": False,
+ "schema": {"title": "Data", "type": "string"},
+ "examples": {
+ "example1": {
+ "summary": "header example 1",
+ "value": "header1",
+ },
+ "example2": {"value": "header2"},
+ },
+ "name": "data",
+ "in": "header",
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ },
+ "/header_example_examples/": {
+ "get": {
+ "summary": "Header Example Examples",
+ "operationId": "header_example_examples_header_example_examples__get",
+ "parameters": [
+ {
+ "required": False,
+ "schema": {"title": "Data", "type": "string"},
+ "examples": {
+ "example1": {
+ "summary": "Qeury example 1",
+ "value": "header1",
+ },
+ "example2": {"value": "header2"},
+ },
+ "name": "data",
+ "in": "header",
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ },
+ "/cookie_example/": {
+ "get": {
+ "summary": "Cookie Example",
+ "operationId": "cookie_example_cookie_example__get",
+ "parameters": [
+ {
+ "required": False,
+ "schema": {"title": "Data", "type": "string"},
+ "example": "cookie1",
+ "name": "data",
+ "in": "cookie",
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ },
+ "/cookie_examples/": {
+ "get": {
+ "summary": "Cookie Examples",
+ "operationId": "cookie_examples_cookie_examples__get",
+ "parameters": [
+ {
+ "required": False,
+ "schema": {"title": "Data", "type": "string"},
+ "examples": {
+ "example1": {
+ "summary": "cookie example 1",
+ "value": "cookie1",
+ },
+ "example2": {"value": "cookie2"},
+ },
+ "name": "data",
+ "in": "cookie",
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ },
+ "/cookie_example_examples/": {
+ "get": {
+ "summary": "Cookie Example Examples",
+ "operationId": "cookie_example_examples_cookie_example_examples__get",
+ "parameters": [
+ {
+ "required": False,
+ "schema": {"title": "Data", "type": "string"},
+ "examples": {
+ "example1": {
+ "summary": "Qeury example 1",
+ "value": "cookie1",
+ },
+ "example2": {"value": "cookie2"},
+ },
+ "name": "data",
+ "in": "cookie",
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ },
+ },
+ "components": {
+ "schemas": {
+ "HTTPValidationError": {
+ "title": "HTTPValidationError",
+ "type": "object",
+ "properties": {
+ "detail": {
+ "title": "Detail",
+ "type": "array",
+ "items": {"$ref": "#/components/schemas/ValidationError"},
+ }
+ },
+ },
+ "Item": {
+ "title": "Item",
+ "required": ["data"],
+ "type": "object",
+ "properties": {"data": {"title": "Data", "type": "string"}},
+ "example": {"data": "Data in schema_extra"},
+ },
+ "ValidationError": {
+ "title": "ValidationError",
+ "required": ["loc", "msg", "type"],
+ "type": "object",
+ "properties": {
+ "loc": {
+ "title": "Location",
+ "type": "array",
+ "items": {"type": "string"},
+ },
+ "msg": {"title": "Message", "type": "string"},
+ "type": {"title": "Error Type", "type": "string"},
+ },
+ },
+ }
+ },
+}
+
+
+def test_openapi_schema():
+ """
+ Test that example overrides work:
+
+ * pydantic model schema_extra is included
+ * Body(example={}) overrides schema_extra in pydantic model
+ * Body(examples{}) overrides Body(example={}) and schema_extra in pydantic model
+ """
+ response = client.get("/openapi.json")
+ assert response.status_code == 200, response.text
+ assert response.json() == openapi_schema
+
+
+def test_call_api():
+ response = client.post("/schema_extra/", json={"data": "Foo"})
+ assert response.status_code == 200, response.text
+ response = client.post("/example/", json={"data": "Foo"})
+ assert response.status_code == 200, response.text
+ response = client.post("/examples/", json={"data": "Foo"})
+ assert response.status_code == 200, response.text
+ response = client.post("/example_examples/", json={"data": "Foo"})
+ assert response.status_code == 200, response.text
+ response = client.get("/path_example/foo")
+ assert response.status_code == 200, response.text
+ response = client.get("/path_examples/foo")
+ assert response.status_code == 200, response.text
+ response = client.get("/path_example_examples/foo")
+ assert response.status_code == 200, response.text
+ response = client.get("/query_example/")
+ assert response.status_code == 200, response.text
+ response = client.get("/query_examples/")
+ assert response.status_code == 200, response.text
+ response = client.get("/query_example_examples/")
+ assert response.status_code == 200, response.text
+ response = client.get("/header_example/")
+ assert response.status_code == 200, response.text
+ response = client.get("/header_examples/")
+ assert response.status_code == 200, response.text
+ response = client.get("/header_example_examples/")
+ assert response.status_code == 200, response.text
+ response = client.get("/cookie_example/")
+ assert response.status_code == 200, response.text
+ response = client.get("/cookie_examples/")
+ assert response.status_code == 200, response.text
+ response = client.get("/cookie_example_examples/")
+ assert response.status_code == 200, response.text
diff --git a/tests/test_tutorial/test_schema_extra_example/__init__.py b/tests/test_tutorial/test_schema_extra_example/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/test_tutorial/test_schema_extra_example/test_tutorial004.py b/tests/test_tutorial/test_schema_extra_example/test_tutorial004.py
new file mode 100644
index 000000000..89f5b66fd
--- /dev/null
+++ b/tests/test_tutorial/test_schema_extra_example/test_tutorial004.py
@@ -0,0 +1,134 @@
+from fastapi.testclient import TestClient
+
+from docs_src.schema_extra_example.tutorial004 import app
+
+client = TestClient(app)
+
+openapi_schema = {
+ "openapi": "3.0.2",
+ "info": {"title": "FastAPI", "version": "0.1.0"},
+ "paths": {
+ "/items/{item_id}": {
+ "put": {
+ "summary": "Update Item",
+ "operationId": "update_item_items__item_id__put",
+ "parameters": [
+ {
+ "required": True,
+ "schema": {"title": "Item Id", "type": "integer"},
+ "name": "item_id",
+ "in": "path",
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {"$ref": "#/components/schemas/Item"},
+ "examples": {
+ "normal": {
+ "summary": "A normal example",
+ "description": "A **normal** item works correctly.",
+ "value": {
+ "name": "Foo",
+ "description": "A very nice Item",
+ "price": 35.4,
+ "tax": 3.2,
+ },
+ },
+ "converted": {
+ "summary": "An example with converted data",
+ "description": "FastAPI can convert price `strings` to actual `numbers` automatically",
+ "value": {"name": "Bar", "price": "35.4"},
+ },
+ "invalid": {
+ "summary": "Invalid data is rejected with an error",
+ "value": {
+ "name": "Baz",
+ "price": "thirty five point four",
+ },
+ },
+ },
+ }
+ },
+ "required": True,
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "HTTPValidationError": {
+ "title": "HTTPValidationError",
+ "type": "object",
+ "properties": {
+ "detail": {
+ "title": "Detail",
+ "type": "array",
+ "items": {"$ref": "#/components/schemas/ValidationError"},
+ }
+ },
+ },
+ "Item": {
+ "title": "Item",
+ "required": ["name", "price"],
+ "type": "object",
+ "properties": {
+ "name": {"title": "Name", "type": "string"},
+ "description": {"title": "Description", "type": "string"},
+ "price": {"title": "Price", "type": "number"},
+ "tax": {"title": "Tax", "type": "number"},
+ },
+ },
+ "ValidationError": {
+ "title": "ValidationError",
+ "required": ["loc", "msg", "type"],
+ "type": "object",
+ "properties": {
+ "loc": {
+ "title": "Location",
+ "type": "array",
+ "items": {"type": "string"},
+ },
+ "msg": {"title": "Message", "type": "string"},
+ "type": {"title": "Error Type", "type": "string"},
+ },
+ },
+ }
+ },
+}
+
+
+def test_openapi_schema():
+ response = client.get("/openapi.json")
+ assert response.status_code == 200, response.text
+ assert response.json() == openapi_schema
+
+
+# Test required and embedded body parameters with no bodies sent
+def test_post_body_example():
+ response = client.put(
+ "/items/5",
+ json={
+ "name": "Foo",
+ "description": "A very nice Item",
+ "price": 35.4,
+ "tax": 3.2,
+ },
+ )
+ assert response.status_code == 200