Compare commits

...

215 Commits

Author SHA1 Message Date
Sebastián Ramírez
51e920e2fc 🔖 Release version 0.62.0 2020-11-29 19:36:38 +01:00
Sebastián Ramírez
c27b9dcf9d 📝 Update release notes, add breaking changes details 2020-11-29 19:35:10 +01:00
Sebastián Ramírez
c7e137c6e0 📝 Update release notes 2020-11-29 19:17:35 +01:00
github-actions
7e4d7fe895 📝 Update release notes 2020-11-29 18:04:51 +00:00
Sebastián Ramírez
2c57ea57bf 🔧 Update TestDriven link to course in sponsors (#2435) 2020-11-29 19:04:27 +01:00
Sebastián Ramírez
be7d15ce3a 📝 Update release notes 2020-11-29 18:55:48 +01:00
github-actions
afc2bb0801 📝 Update release notes 2020-11-29 17:32:46 +00:00
Sebastián Ramírez
313bbe802f Add support for shared/top-level parameters (dependencies, tags, etc) (#2434)
*  Add Default and DefaultPlaceholder data structures

to handle defaults and overrides

*  Add utils to get values by priority handling DefaultPlaceholders

*  Add support for top-level parameters in FastAPI, APIRouter, include_router

including: prefix, tags, dependencies, deprecated, include_in_schema, responses, default_response_class, callbacks

* ♻️ Update openapi utils to handle DefaultPlaceholder for response_class

* 📝 Update bigger-application example code to use top-level params

and showcase them in APIRouter, FastAPI, include_router

* 📝 Update docs for Bigger Applications, include diagrams, top-level params

* 🔥 Simplify code and docs for callbacks as default_response_class is no longer required

* 📝 Add docs for top-level dependencies, in FastAPI()

* 📝 Add docs reference to top-level dependencies in docs for decorator

*  Update/increase tests for Bigger Applications including shared parameters

*  Add tests for top-level dependencies in FastAPI()

*  Add tests for internal DefaultPlaceholder

*  Update/increase tests for callbacks with top-level parameters

*  Add LOTS of tests covering branches and cases for shared parameters

in top-level FastAPI, path operations, include_router, APIRouter, its path operations, nested include_router, nested APIRouter, and its path operations

* 🎨 Format/reorder parameters for consistency in FastAPI, APIRouter, include_router
2020-11-29 18:32:18 +01:00
github-actions
d550738fa2 📝 Update release notes 2020-11-25 17:48:13 +00:00
atsumi
cc99e23e82 🌐 Add Japanese translation for Advanced - Custom Response (#2193)
Co-authored-by: T. Tokusumi <41147016+tokusumi@users.noreply.github.com>
Co-authored-by: Taki Komiyama <39375566+komtaki@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-11-25 18:47:45 +01:00
github-actions
dbdcf86a11 📝 Update release notes 2020-11-25 17:46:45 +00:00
Spaceack
2434980968 🌐 Add Chinese translation for Benchmarks (#2119) 2020-11-25 18:35:39 +01:00
github-actions
ee27f7790f 📝 Update release notes 2020-11-25 17:35:19 +00:00
Xie Wei
d2cc2627ba 🌐 Add Chinese translation for Tutorial - Body - Nested Models (#1609)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-11-25 18:34:50 +01:00
github-actions
f6a285c13c 📝 Update release notes 2020-11-25 17:28:00 +00:00
Ikkyu
8af0b136b1 🌐 Add Chinese translation for Advanced - Custom Response (#1459)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-11-25 18:27:34 +01:00
github-actions
159a61d2b0 📝 Update release notes 2020-11-25 17:23:01 +00:00
Ikkyu
94fe5495fa 🌐 Add Chinese translation for Advanced - Return a Response Directly (#1452)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-11-25 18:22:34 +01:00
github-actions
8cc3ac1329 📝 Update release notes 2020-11-25 17:16:53 +00:00
Ikkyu
6b49f67d11 🌐 Add Chinese translation for Advanced - Additional Status Codes (#1451)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-11-25 18:16:20 +01:00
github-actions
9972b76efa 📝 Update release notes 2020-11-25 17:12:26 +00:00
Ikkyu
410da16a14 🌐 Add Chinese translation for Advanced - Path Operation Advanced Configuration (#1447)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-11-25 18:11:59 +01:00
github-actions
8997f96540 📝 Update release notes 2020-11-25 17:07:41 +00:00
Ikkyu
b8331b13d7 🌐 Add Chinese translation for Advanced User Guide - Intro (#1445)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-11-25 18:07:17 +01:00
github-actions
7a3c244c07 📝 Update release notes 2020-11-25 16:40:33 +00:00
Sebastián Ramírez
7a692d2c7b 🍱 Update sponsor logos (#2418) 2020-11-25 17:40:07 +01:00
github-actions
b53c443a06 📝 Update release notes 2020-11-10 19:52:19 +00:00
Sebastián Ramírez
7d7289aeb8 💚 Fix disabling install of Material for MkDocs Insiders in forks, strike 1 (#2340) 2020-11-10 20:51:56 +01:00
github-actions
24b638faf6 📝 Update release notes 2020-11-10 19:38:22 +00:00
Sebastián Ramírez
2561a17225 🐛 Fix disabling Material for MkDocs Insiders install in forks (#2339) 2020-11-10 20:37:55 +01:00
github-actions
d8cfa8ac87 📝 Update release notes 2020-11-10 19:25:07 +00:00
Sebastián Ramírez
76083559f0 Add silver sponsor WeTransfer (#2338) 2020-11-10 20:24:42 +01:00
github-actions
df56655361 📝 Update release notes 2020-11-08 17:27:00 +00:00
Louis Guitton
2e67f2fa6d 📝 Add FastAPI monitoring blog post to External Links (#2324)
https://github.com/tiangolo/fastapi/issues/1828#issuecomment-723541832
2020-11-08 18:26:34 +01:00
github-actions
ac073b2f5f 📝 Update release notes 2020-11-08 11:43:23 +00:00
Sebastián Ramírez
4bcdbc5673 Set up and enable Material for MkDocs Insiders for the docs (#2325)
* ⬆️ Upgrade Material for MkDocs

* ⬆️ Install Material for MkDocs Insiders on CI

* 🔧 Update MkDocs configs to use Material for MkDocs Insiders

*  Use the lightbulb because it looks nice 💡

* 💚 Fix GitHub Action workflow syntax for building docs

* 🐛 Fix GitHub Actions workflow syntax, strike one 
2020-11-08 12:42:55 +01:00
github-actions
97adeca0a4 📝 Update release notes 2020-11-07 20:48:48 +00:00
Sebastián Ramírez
ac99792762 Add Discord chat (#2322)
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
2020-11-07 21:48:25 +01:00
github-actions
d01e0a10d8 📝 Update release notes 2020-11-07 18:55:35 +00:00
Sebastián Ramírez
de0f466ef8 ✏️ Fix typo in Deta tutorial (#2320) 2020-11-07 19:55:12 +01:00
Sebastián Ramírez
77f7447ee8 📝 Update release notes 2020-11-06 00:14:52 +01:00
github-actions
48827eb7fc 📝 Update release notes 2020-11-05 23:13:28 +00:00
Sebastián Ramírez
5786d2ef78 📝 Fix image links for sponsors (#2304) 2020-11-06 00:13:04 +01:00
Sebastián Ramírez
166088775a 🔖 Release version 0.61.2 2020-11-06 00:04:32 +01:00
Sebastián Ramírez
1052914c20 📝 Update release notes 2020-11-06 00:03:52 +01:00
github-actions
7bdc86b6b4 📝 Update release notes 2020-11-05 22:53:41 +00:00
Camila Gutierrez
733218f199 ✏️ Fix typo in Tutorial - Path Parameters (#2231) 2020-11-05 23:53:10 +01:00
github-actions
3fb6d2982f 📝 Update release notes 2020-11-05 22:52:49 +00:00
David Dobrinskiy
b323726d86 ✏ Fix a stylistic error in docs (#2206) 2020-11-05 23:52:17 +01:00
github-actions
2db2381b68 📝 Update release notes 2020-11-05 22:51:01 +00:00
atsumi
d31648c82e 🌐 Add Japanese translation for Advanced Tutorial - Response Directly (#2191)
* Add Japanese translation for Advanced - response-directly

* Apply suggestions from code review

Co-authored-by: T. Tokusumi <41147016+tokusumi@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Taki Komiyama <39375566+komtaki@users.noreply.github.com>

Co-authored-by: T. Tokusumi <41147016+tokusumi@users.noreply.github.com>
Co-authored-by: Taki Komiyama <39375566+komtaki@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-11-05 23:50:38 +01:00
github-actions
e6c2343691 📝 Update release notes 2020-11-05 22:45:29 +00:00
谭九鼎
ab0379ee52 ✏ Fix capitalizaiton typo in docs (#2204) 2020-11-05 23:44:56 +01:00
github-actions
790fa217f7 📝 Update release notes 2020-11-05 22:42:49 +00:00
Ammar Asmro
b892b5e028 ✏ Fix typo in docs (#2179) 2020-11-05 23:42:07 +01:00
github-actions
39eedb31f7 📝 Update release notes 2020-11-05 22:39:33 +00:00
谭九鼎
8355832c7c 📝 Update/fix links in docs to use HTTPS (#2165)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-11-05 23:39:09 +01:00
github-actions
5821ea8a69 📝 Update release notes 2020-11-05 22:34:08 +00:00
nukopy
3dbdc74366 ✏ Fix typos and add rewording in docs (#2159)
* docs: fix typo in chapter "Request Body" in "Tutorial - User Guide"

* docs: modify a sentence in chapter "Query Parameters and String Validations" in "Tutorial - User Guide"

* docs: fix two grammatical mistakes in chapter "Path Parameters and Numeric Validations" in "Tutorial - User Guide"
2020-11-05 23:33:06 +01:00
github-actions
939acef803 📝 Update release notes 2020-11-05 22:31:20 +00:00
nukopy
22a5960d36 📝 Fix code consistency in examples for Tutorial - User Guide - Path Parameters (#2158) 2020-11-05 23:30:09 +01:00
github-actions
8c5efe0b4b 📝 Update release notes 2020-11-05 22:29:07 +00:00
Teofilo Zosa
730ded2870 📝 Fix renamed parameter content_type typo (#2135) 2020-11-05 23:26:28 +01:00
github-actions
1a000d7e5f 📝 Update release notes 2020-11-05 22:24:33 +00:00
Taki Komiyama
104ee630fc 📝 Add Japanese translation for Tutorial - Security - First Steps (#2153)
Co-authored-by: atsumi <atsumi.tatsuya@gmail.com>
Co-authored-by: T. Tokusumi <41147016+tokusumi@users.noreply.github.com>
2020-11-05 23:24:05 +01:00
github-actions
ea69c373ac 📝 Update release notes 2020-11-05 22:21:54 +00:00
Teofilo Zosa
9118749128 ✏ Fix minor typos in docs (#2122) 2020-11-05 23:20:55 +01:00
github-actions
87ad6a46e8 📝 Update release notes 2020-11-05 22:14:40 +00:00
Adrian
75c64b6e4c ✏ Fix typos in docs and source examples (#2102)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-11-05 23:14:17 +01:00
github-actions
ccd3b97f03 📝 Update release notes 2020-11-05 22:03:04 +00:00
Nutchanon Ninyawee
074d39fa17 ✏ Fix incorrect Celery URLs in docs (#2100) 2020-11-05 23:02:07 +01:00
github-actions
f1419322b3 📝 Update release notes 2020-11-05 21:58:33 +00:00
John Riebold
b8e6d18385 📌 Relax Swagger UI version pin (#2089) 2020-11-05 22:57:16 +01:00
github-actions
82a1300257 📝 Update release notes 2020-11-05 21:56:17 +00:00
Aaron Christianson
13d9de4a49 📝 Simplify intro to Python Types, all currently supported Python versions include type hints 🎉 (#2085) 2020-11-05 22:53:44 +01:00
github-actions
f931dd0717 📝 Update release notes 2020-11-05 21:44:18 +00:00
Sebastián Ramírez
24d2226326 Fix tags's declare (#2054) 2020-11-05 22:43:28 +01:00
github-actions
0c895f1eaf 📝 Update release notes 2020-11-05 21:42:54 +00:00
hitrust
c041c52d91 📝 Fix example code with sets in Tutorial - Body - Nested Models 2 (#2053) 2020-11-05 22:41:45 +01:00
github-actions
cc9e6b3484 📝 Update release notes 2020-11-05 21:39:59 +00:00
hitrust
dfcc6bc154 📝 Fix example code with sets in Tutorial - Body - Nested Models (#2052) 2020-11-05 22:38:59 +01:00
github-actions
7e708f7411 📝 Update release notes 2020-11-05 21:32:20 +00:00
Alejo Carballude
e09646441d ✏ Fix typo in Benchmarks (#1995) 2020-11-05 22:31:38 +01:00
github-actions
1631f981af 📝 Update release notes 2020-11-05 21:22:25 +00:00
Yurii Karabas
4ce18167e7 🐛 Fix bug overriding custom HTTPException and RequestValidationError from exception_handlers (#1924) 2020-11-05 22:21:40 +01:00
github-actions
a676899557 📝 Update release notes 2020-11-05 21:10:35 +00:00
Marcelo Trylesinski
b299792ebf ✏️ Fix typo on dependencies utils and cleanup unused variable (#1912) 2020-11-05 22:09:17 +01:00
github-actions
9fcec3abe9 📝 Update release notes 2020-11-05 21:05:15 +00:00
Daniel Murrell
5df00f3ec4 📝 Add note in CORS tutorial about allow_origins with ["*"] and allow_credentials (#1895) 2020-11-05 22:03:45 +01:00
github-actions
20ba6e8b97 📝 Update release notes 2020-11-05 20:51:04 +00:00
Sebastián Ramírez
a42c690496 📝 Add deployment to Deta, the first gold sponsor 🎉 (#2303)
* 📝 Add docs for sponsors

* 📝 Add docs for deploying on Deta

* 🍱 Add Deta docs screenshots

* ♻️ Refactor and separate deployment docs

* 📝 Update internal docs links to Deployment

* 📝 Update links in Deta tutorial

* 🍱 Update sponsors images

* 🔧 Use sponsors data from YAML

* 📝 Update sponsors in languages docs

*  Update docs generation scripts

*  Update README.md testing

* 📝 Update main README

* 🔧 Update fastapi-people action handling individual sponsors

* ✏️ Fix typos in Deta tutorial
2020-11-05 21:50:37 +01:00
github-actions
bed0f065fa 📝 Update release notes 2020-11-01 21:54:32 +00:00
SwftAlpc
76632fcf24 🌐 Add Japanese translation for Tutorial - Query Parameters and String Validations (#1901)
Co-authored-by: atsumi <atsumi.tatsuya@gmail.com>
Co-authored-by: ryusuke.miyaji <bluce826@gmail.com>
Co-authored-by: ryuckel <36391432+ryuckel@users.noreply.github.com>
Co-authored-by: tokusumi <tksmtoms@gmail.com>
Co-authored-by: T. Tokusumi <41147016+tokusumi@users.noreply.github.com>
2020-11-01 22:54:05 +01:00
github-actions
32a010394f 📝 Update release notes 2020-11-01 21:40:13 +00:00
github-actions[bot]
8d572faa24 👥 Update FastAPI People (#2282)
Co-authored-by: github-actions <github-actions@github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-11-01 22:39:51 +01:00
github-actions
f495d98fae 📝 Update release notes 2020-10-25 18:48:12 +00:00
Camila Gutierrez
3702cef08d ✏️ Fix uppercase in Tutorial - Query Parameters (#2245) 2020-10-25 19:47:46 +01:00
github-actions
9474706ec2 📝 Update release notes 2020-10-25 18:46:59 +00:00
Sebastián Ramírez
e1755f4fa6 🔥 Cleanup after upgrade for Docs Previews GitHub Action (#2248)
* 🔧 Upload docs artifacts even on push to avoid breaking Preview Docs

* 🔥 Remove replaced GitHub Action get-artifact

* 🔥 Remove GitHub Action Watch Docs Previews, replaced with Preview Docs

* 🔥 Remove commented backup configs in Preview Docs GitHub Action

* 🔥 Remove no longer needed utils scripts
2020-10-25 19:46:32 +01:00
github-actions
c75c13c3b0 📝 Update release notes 2020-10-25 18:25:55 +00:00
Sebastián Ramírez
8673e1c127 📝 Add articles to External Links (#2247) 2020-10-25 19:25:31 +01:00
github-actions
360868fe25 📝 Update release notes 2020-10-25 18:12:21 +00:00
Sebastián Ramírez
b46b3f00bf 🐛 Fix unzip docs preview in CI (#2246) 2020-10-25 19:12:00 +01:00
github-actions
c6e950dc9c 📝 Update release notes 2020-10-25 17:54:58 +00:00
Sebastián Ramírez
4e74d40736 Add instant docs deploy previews for PRs from forks (#2244)
* 🔥 Disable action Watch Docs Previews

* 🔧 Use predefined name for docs artifacts for previews

*  Add new GitHub Action Comment Docs Preview in PR

* 🔧 Refactor GitHub Action Preview Docs to work as workflow_run using new action to extract where to comment
2020-10-25 18:54:36 +01:00
github-actions
612d114f3a 📝 Update release notes 2020-10-25 11:59:34 +00:00
Sebastián Ramírez
f88ffd1a0b ️ Build docs for languages in parallel in subprocesses to speed up CI (#2242) 2020-10-25 12:59:13 +01:00
github-actions
cdf0f8a933 📝 Update release notes 2020-10-24 11:33:24 +00:00
Sebastián Ramírez
8650dee4bc 🐛 Fix docs order generation for partial translations (#2238) 2020-10-24 13:32:59 +02:00
github-actions
dca9cc3ec5 📝 Update release notes 2020-10-18 20:19:45 +00:00
github-actions[bot]
d6f37b2138 👥 Update FastAPI People (#2202)
Co-authored-by: github-actions <github-actions@github.com>
2020-10-18 22:19:01 +02:00
github-actions
5a13f78078 📝 Update release notes 2020-10-18 20:16:53 +00:00
Sebastián Ramírez
d625963cc5 ♻️ Update FastAPI People GitHub Action to send the PR as github-actions (#2201) 2020-10-18 22:16:12 +02:00
github-actions
142710a0f3 📝 Update release notes 2020-10-18 20:05:19 +00:00
Sebastián Ramírez
47fcacd4d6 🔧 Update FastAPI People GitHub Action config, run monthly (#2199) 2020-10-18 22:04:32 +02:00
github-actions
00104c9259 📝 Update release notes 2020-10-18 19:57:42 +00:00
Sebastián Ramírez
8386e61f17 🐛 Fix FastAPI People GitHub Action Docker dependency, strike 1 (#2198) 2020-10-18 21:57:02 +02:00
github-actions
9b7125f66b 📝 Update release notes 2020-10-18 19:52:30 +00:00
Sebastián Ramírez
68dc9bd5ac 🐛 Fix FastAPI People GitHub Action Docker dependencies (#2197) 2020-10-18 21:51:51 +02:00
github-actions
7a02d862aa 📝 Update release notes 2020-10-18 19:45:51 +00:00
Sebastián Ramírez
479e87e467 🐛 Fix FastAPI People GitHub Action when there's nothing to change (#2196) 2020-10-18 21:45:10 +02:00
github-actions
1ea24e1813 📝 Update release notes 2020-10-18 19:36:23 +00:00
Sebastián Ramírez
492c0924c4 👥 Add new section FastAPI People (#2195)
* 👥 Update FastAPI People

*  Add first version of FastAPI People GitHub action code

* 🐳 Add Docker and configs for the FastAPI People GitHub Action

* 👷 Add GitHub Action workflow for FastAPI People

* 📝 Add FastAPI People to docs

* 💄 Add custom CSSs for FastAPI People
2020-10-18 21:35:42 +02:00
github-actions
048355f01d 📝 Update release notes 2020-10-18 07:05:30 +00:00
Fabio Serrao
fe889f38e8 🌐 Add Portuguese translation for External Links (#1443)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-10-18 09:04:47 +02:00
github-actions
1dd2bc7675 📝 Update release notes 2020-10-18 06:03:03 +00:00
T. Tokusumi
91ffa0ed27 🌐 Add Japanese translation for Tutorial - CORS (#2125)
Co-authored-by: Taki Komiyama <39375566+komtaki@users.noreply.github.com>
Co-authored-by: atsumi <atsumi.tatsuya@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-10-18 08:02:19 +02:00
github-actions
6ab0f89858 📝 Update release notes 2020-10-18 05:57:45 +00:00
Taki Komiyama
bfc9733660 🌐 Add Japanese translation for Contributing (#2067)
Co-authored-by: atsumi <atsumi.tatsuya@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-10-18 07:57:05 +02:00
github-actions
9c00618710 📝 Update release notes 2020-10-18 05:48:25 +00:00
T. Tokusumi
beedd199e8 🌐 Add Japanese translation for Project Generation (#2050)
Co-authored-by: Taki Komiyama <39375566+komtaki@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-10-18 07:47:45 +02:00
github-actions
ae580deaea 📝 Update release notes 2020-10-18 05:38:53 +00:00
atsumi
e1231eeef1 🌐 Add Japanese translation for Alternatives (#2043)
Co-authored-by: Taki Komiyama <39375566+komtaki@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-10-18 07:38:09 +02:00
github-actions
8a1ebb38e2 📝 Update release notes 2020-10-18 05:30:50 +00:00
Juan Sebastian Avila Rodriguez
e9413f2711 ✏ Fix typo in Spanish tutorial index (#2020) 2020-10-18 07:28:44 +02:00
github-actions
7434d2bec7 📝 Update release notes 2020-10-18 05:26:55 +00:00
Taki Komiyama
f2c565d8e4 🌐 Add Japanese translation for History Design and Future (#2002)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-10-18 07:26:14 +02:00
github-actions
cb55d7cdde 📝 Update release notes 2020-10-17 18:44:24 +00:00
Taki Komiyama
d513680005 🌐 Add Japanese translation for Benchmarks (#1992)
Co-authored-by: atsumi <atsumi.tatsuya@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-10-17 20:43:43 +02:00
github-actions
a5ee4d93d2 📝 Update release notes 2020-10-17 13:56:21 +00:00
SwftAlpc
3a2d4434ce 🌐 Add Japanese translation for Tutorial - Header Parameters (#1935)
Co-authored-by: ryusuke.miyaji <bluce826@gmail.com>
Co-authored-by: ryuckel <36391432+ryuckel@users.noreply.github.com>
Co-authored-by: tokusumi <tksmtoms@gmail.com>
Co-authored-by: T. Tokusumi <41147016+tokusumi@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-10-17 15:55:39 +02:00
github-actions
d1dfc812f1 📝 Update release notes 2020-10-17 13:46:12 +00:00
Sebastián Ramírez
0b76b675db ⬆️ Upgrade GitHub Action Latest Changes (#2190) 2020-10-17 15:45:33 +02:00
github-actions
5a776fbff5 📝 Update release notes 2020-10-17 13:40:03 +00:00
Sebastián Ramírez
7667605520 ⬆️ Upgrade GitHub Action Label Approved (#2189) 2020-10-17 15:39:24 +02:00
github-actions
642762564d 📝 Update release notes 2020-10-17 10:43:35 +00:00
Jéssica Paz
78ead585f8 🌐 Add Portuguese translation for Tutorial - First Steps (#1861)
Co-authored-by: deniscapeto <deniscapeto@gmail.com>
2020-10-17 12:41:44 +02:00
github-actions
48bf243050 📝 Update release notes 2020-10-17 06:43:16 +00:00
Sebastián Ramírez
0e920e6f02 🌐 Add Portuguese translation for Python Types (#1796)
* Portuguese translation python-types

* Change 'dicas de tipo' to 'type hints'
2020-10-17 08:40:31 +02:00
github-actions
afac22dfd2 📝 Update release notes 2020-10-17 06:39:20 +00:00
T. Tokusumi
2836e10e2d 🌐 Add Japanese translation for Help FastAPI (#1692)
Co-authored-by: Taki Komiyama <39375566+komtaki@users.noreply.github.com>
Co-authored-by: ryusuke.miyaji <bluce826@gmail.com>
Co-authored-by: ryuckel <36391432+ryuckel@users.noreply.github.com>
Co-authored-by: Taki Komiyama <39375566+komtaki@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-10-17 08:38:37 +02:00
github-actions
aa62d9212f 📝 Update release notes 2020-10-17 06:32:39 +00:00
T. Tokusumi
620bffc2b4 🌐 Add Japanese translation for Tutorial - Body (#1683)
Co-authored-by: ryusuke.miyaji <bluce826@gmail.com>
Co-authored-by: ryuckel <36391432+ryuckel@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-10-17 08:31:55 +02:00
github-actions
b56cf6c08f 📝 Update release notes 2020-10-17 06:24:33 +00:00
T. Tokusumi
cead6ba887 🌐 Add Japanese translation for Tutorial - Query Params (#1674)
Co-authored-by: ryusuke.miyaji <bluce826@gmail.com>
Co-authored-by: ryuckel <36391432+ryuckel@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-10-17 08:23:51 +02:00
github-actions
23772f3c49 📝 Update release notes 2020-10-17 06:15:44 +00:00
T. Tokusumi
45304562a6 🌐 Add Japanese translation for tutorial/path-params.md (#1671)
Co-authored-by: ryusuke.miyaji <bluce826@gmail.com>
Co-authored-by: ryuckel <36391432+ryuckel@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-10-17 08:15:05 +02:00
github-actions
3d767008df 📝 Update release notes 2020-10-17 06:09:43 +00:00
T. Tokusumi
5c6811c4ef Add Japanese translation for tutorial/first-steps.md (#1658)
Co-authored-by: ryusuke.miyaji <bluce826@gmail.com>
Co-authored-by: ryuckel <36391432+ryuckel@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-10-17 08:09:01 +02:00
github-actions
25e1a2602d 📝 Update release notes 2020-10-17 06:03:36 +00:00
T. Tokusumi
b6272a36af 🌐 Add Japanese translation for tutorial/index.md (#1656)
Co-authored-by: ryusuke.miyaji <bluce826@gmail.com>
Co-authored-by: ryuckel <36391432+ryuckel@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-10-17 08:02:56 +02:00
github-actions
db91255ede 📝 Update release notes 2020-10-17 05:51:31 +00:00
Fabio Serrao
ab52e1c7e4 🌐 Add translation to Portuguese for Project Generation (#1602)
* Portuguese translation project-generation

* Update docs/pt/docs/project-generation.md

Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>

* Update docs/pt/docs/project-generation.md

Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>

* Update docs/pt/docs/project-generation.md

Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>

* Update docs/pt/docs/project-generation.md

Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>

* Update docs/pt/docs/project-generation.md

Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>

* Update docs/pt/docs/project-generation.md

Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>

* Update docs/pt/docs/project-generation.md

Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>

* Update docs/pt/docs/project-generation.md

Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>

* Update docs/pt/docs/project-generation.md

Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>

* Update docs/pt/docs/project-generation.md

Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>

* Update docs/pt/docs/project-generation.md

* ✏ Fix typo in docs/pt/docs/project-generation.md

Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-10-17 07:50:32 +02:00
github-actions
4924d08e7e 📝 Update release notes 2020-10-16 20:35:50 +00:00
Sebastián Ramírez
a7c65271ac 🔧 Update GitHub Action Label Approved, run at 12:00 (#2185) 2020-10-16 22:35:07 +02:00
github-actions
030f1f2ae2 📝 Update release notes 2020-10-16 20:09:35 +00:00
T. Tokusumi
74f13e522b 🌐 Add Japanese translation for Features (#1625)
Co-authored-by: ryusuke.miyaji <bluce826@gmail.com>
Co-authored-by: ryuckel <36391432+ryuckel@users.noreply.github.com>
2020-10-16 22:08:18 +02:00
github-actions
a4f88f74f2 📝 Update release notes 2020-10-16 20:04:38 +00:00
Sebastián Ramírez
3826129b16 👷 Upgrade GitHub Action Latest Changes (#2184) 2020-10-16 22:04:12 +02:00
Sebastián Ramírez
636f06cd6b 📝 Update release notes 2020-10-15 07:26:26 +02:00
hard_coder
c8365bd339 🌐 Initialize new language Korean for translations (#2018) 2020-10-15 07:21:41 +02:00
Sebastián Ramírez
df38e53723 📝 Update release notes 2020-10-11 17:04:21 +02:00
Fabio Serrao
c606407929 🌐 Add Portuguese translation of Deployment (#1374) 2020-10-11 12:46:20 +02:00
github-actions
f59f85d755 📝 Update release notes 2020-10-11 10:41:42 +00:00
Sebastián Ramírez
42bb15de22 👷 Set GitHub Action Label Approved to run daily, not every minute (#2163) 2020-10-11 12:41:16 +02:00
Sebastián Ramírez
e96b002599 📝 Update release notes 2020-10-11 12:06:07 +02:00
github-actions
75b83ce3aa 📝 Update release notes 2020-10-11 10:04:35 +00:00
Sebastián Ramírez
ad5aa33864 🔥 Remove pr-approvals GitHub Action as it's not compatible with forks. Use the new one (#2162)
as it is not compatible with forks
2020-10-11 12:04:04 +02:00
Sebastián Ramírez
952cd736ac 👷 Add GitHub Action Label Approved (#2161) 2020-10-11 11:53:25 +02:00
Sebastián Ramírez
026039cae2 📝 Update release notes 2020-10-11 11:51:49 +02:00
Sebastián Ramírez
e2609dff95 👷 Add GitHub Action Latest Changes (#2160) 2020-10-11 11:50:04 +02:00
hitrust
8486b41349 Fix tags's declare 2020-09-15 14:40:49 +08:00
Sebastián Ramírez
e77ea63577 🔖 Release version 0.61.1 2020-08-29 16:30:50 +02:00
Sebastián Ramírez
097df92c1c 📝 Update release notes 2020-08-29 16:06:32 +02:00
Brock Friedrich
be669059fb 🎨 Simplify docs hl_lines ranges and standardize 2 spaces between each range (#1863) 2020-08-29 16:02:58 +02:00
Sebastián Ramírez
dfdd371c52 📝 Update release notes 2020-08-29 15:38:44 +02:00
ryuckel
e1e8627168 🌐 Add Japanese translation for index.md (#1571) 2020-08-29 15:34:08 +02:00
Sebastián Ramírez
0916c1c3ef 📝 Update release notes 2020-08-29 14:32:08 +02:00
Facundo Maero
11656f7bd5 ✏ Fix typo in nosql-databases.md (#1980)
Co-authored-by: Facundo Maero <facundo.maero@deepvisionai.com>
2020-08-29 14:30:23 +02:00
Sebastián Ramírez
483d092af8 📝 Update release notes 2020-08-29 14:29:00 +02:00
JulianMaurin
60aa63b68a 🌐 Initialize translations for French (#1975)
Co-authored-by: JulianMaurin <julian.maurin.perso@pm.me>
2020-08-29 14:27:34 +02:00
Sebastián Ramírez
eb547bd4fd 📝 Update release notes 2020-08-29 14:24:24 +02:00
Sebastián Ramírez
0dfde6e284 🐛 Fix issues introduced by removing sqlalchemy safeguard in jsonable_encoder (#1987) 2020-08-29 14:21:00 +02:00
Sebastián Ramírez
2d7038e03e 📝 Update release notes 2020-08-29 11:47:13 +02:00
Yağızcan Değirmenci
4f0a3a9e4d 🌐 Initialize Turkish translations (#1905) 2020-08-29 11:43:29 +02:00
Izabela Guerreiro
1701930c86 Change 'dicas de tipo' to 'type hints' 2020-08-11 10:23:23 -03:00
Sebastián Ramírez
a6897963d5 🔖 Release version 0.61.0 2020-08-09 22:36:47 +02:00
Sebastián Ramírez
c14803e3fa 📝 Update release notes 2020-08-09 22:34:50 +02:00
Sebastián Ramírez
cdba8481c2 🔥 Remove old/unused parameter sqlalchemy_safe from jsonable_encoder (#1864) 2020-08-09 22:32:59 +02:00
Sebastián Ramírez
64ca596a11 📝 Update release notes 2020-08-09 22:19:46 +02:00
Sebastián Ramírez
e1758d107e ⬆ Require Pydantic > 1.0 (#1862)
* 🔥 Remove support for Pydantic < 1.0

* 🔥 Remove deprecated skip_defaults from jsonable_encoder and set default for exclude to None, as in Pydantic

* ♻️ Set default of response_model_exclude=None as in Pydantic

* ⬆️ Require Pydantic >=1.0.0 in requirements
2020-08-09 22:17:08 +02:00
Sebastián Ramírez
3390182fc9 📝 Update release notes 2020-08-09 17:04:35 +02:00
Sebastián Ramírez
912a43ee3d 📝 Add link to TestDriven.io course in docs (#1860) 2020-08-09 17:02:51 +02:00
Sebastián Ramírez
4020304945 📝 Update release notes 2020-08-09 16:43:07 +02:00
Elliana May
0a2fc78fea ✏️ Update docs to remove gender-specific references (#1824)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-08-09 16:35:44 +02:00
Sebastián Ramírez
b91acfb457 📝 Update release notes 2020-08-09 15:58:58 +02:00
Nik
b9a0179a03 Add support for injecting HTTPConnection (#1827) 2020-08-09 15:56:41 +02:00
Rupsi Kaushik
5ed48ccdc8 Export WebSocketDisconnect and add example handling disconnections to docs (#1822)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-08-09 15:52:19 +02:00
Sebastián Ramírez
f32d67c8b9 📝 Update release notes 2020-08-09 13:12:09 +02:00
manlix
0752c7242d 🔊 Fix empty log message in docs example about raised exceptions (#1815) 2020-08-09 13:10:33 +02:00
Sebastián Ramírez
be855c696b 📝 Update release notes 2020-08-09 12:56:09 +02:00
Nima Mashhadi M. Reza
da9b5201c4 🔧 Add Flake8 linting (#1774)
Co-authored-by: nimashadix <nimashadix@pop-os.localdomain>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-08-09 12:54:05 +02:00
Sebastián Ramírez
4daa6ef4e4 📝 Update release notes 2020-08-09 11:08:29 +02:00
Sebastián Ramírez
4ad7c55618 💚 Disable Gitter notification as it's currently broken (#1853)
...no idea why yet. 😔
2020-08-08 20:43:31 +02:00
Izabela Guerreiro
9cc4428de3 Portuguese translation python-types 2020-07-26 23:00:28 -03:00
240 changed files with 18809 additions and 1773 deletions

5
.flake8 Normal file
View File

@@ -0,0 +1,5 @@
[flake8]
max-line-length = 88
select = C,E,F,W,B,B9
ignore = E203, E501, W503
exclude = __init__.py

View File

@@ -1,6 +1,6 @@
FROM python:3.7
RUN pip install httpx "pydantic==1.5.1"
RUN pip install httpx "pydantic==1.5.1" pygithub
COPY ./app /app

View File

@@ -0,0 +1,13 @@
name: Comment Docs Preview in PR
description: Comment with the docs URL preview in the PR
author: Sebastián Ramírez <tiangolo@gmail.com>
inputs:
token:
description: Token for the repo. Can be passed in using {{ secrets.GITHUB_TOKEN }}
required: true
deploy_url:
description: The deployment URL to comment in the PR
required: true
runs:
using: docker
image: Dockerfile

View File

@@ -0,0 +1,70 @@
import logging
import sys
from pathlib import Path
from typing import Optional
import httpx
from github import Github
from github.PullRequest import PullRequest
from pydantic import BaseModel, BaseSettings, SecretStr, ValidationError
github_api = "https://api.github.com"
class Settings(BaseSettings):
github_repository: str
github_event_path: Path
github_event_name: Optional[str] = None
input_token: SecretStr
input_deploy_url: str
class PartialGithubEventHeadCommit(BaseModel):
id: str
class PartialGithubEventWorkflowRun(BaseModel):
head_commit: PartialGithubEventHeadCommit
class PartialGithubEvent(BaseModel):
workflow_run: PartialGithubEventWorkflowRun
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
settings = Settings()
logging.info(f"Using config: {settings.json()}")
g = Github(settings.input_token.get_secret_value())
repo = g.get_repo(settings.github_repository)
try:
event = PartialGithubEvent.parse_file(settings.github_event_path)
except ValidationError as e:
logging.error(f"Error parsing event file: {e.errors()}")
sys.exit(0)
use_pr: Optional[PullRequest] = None
for pr in repo.get_pulls():
if pr.head.sha == event.workflow_run.head_commit.id:
use_pr = pr
break
if not use_pr:
logging.error(
f"No PR found for hash: {event.workflow_run.head_commit.id}"
)
sys.exit(0)
github_headers = {
"Authorization": f"token {settings.input_token.get_secret_value()}"
}
url = f"{github_api}/repos/{settings.github_repository}/issues/{use_pr.number}/comments"
logging.info(f"Using comments URL: {url}")
response = httpx.post(
url,
headers=github_headers,
json={
"body": f"📝 Docs preview for commit {use_pr.head.sha} at: {settings.input_deploy_url}"
},
)
if not (200 <= response.status_code <= 300):
logging.error(f"Error posting comment: {response.text}")
sys.exit(1)
logging.info("Finished")

View File

@@ -1,16 +0,0 @@
name: "Get Artifact"
description: "Get artifact, possibly uploaded by a PR, useful to deploy docs previews"
author: "Sebastián Ramírez <tiangolo@gmail.com>"
inputs:
token:
description: 'Token for the repo. Can be passed in using {{ secrets.GITHUB_TOKEN }}'
required: true
name:
description: 'Artifact name'
required: true
path:
description: 'Where to store the artifact'
required: true
runs:
using: 'docker'
image: 'Dockerfile'

View File

@@ -1,63 +0,0 @@
import logging
from datetime import datetime
from pathlib import Path
from typing import List, Optional
import httpx
from pydantic import BaseModel, BaseSettings, SecretStr
github_api = "https://api.github.com"
netlify_api = "https://api.netlify.com"
class Settings(BaseSettings):
input_name: str
input_token: SecretStr
input_path: str
github_repository: str
github_event_path: Path
github_event_name: Optional[str] = None
class Artifact(BaseModel):
id: int
node_id: str
name: str
size_in_bytes: int
url: str
archive_download_url: str
expired: bool
created_at: datetime
updated_at: datetime
class ArtifactResponse(BaseModel):
total_count: int
artifacts: List[Artifact]
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
settings = Settings()
logging.info(f"Using config: {settings.json()}")
github_headers = {
"Authorization": f"token {settings.input_token.get_secret_value()}"
}
response = httpx.get(
f"{github_api}/repos/{settings.github_repository}/actions/artifacts",
headers=github_headers,
)
data = response.json()
artifacts_response = ArtifactResponse.parse_obj(data)
use_artifact: Optional[Artifact] = None
for artifact in artifacts_response.artifacts:
if artifact.name == settings.input_name:
use_artifact = artifact
break
assert use_artifact
file_response = httpx.get(
use_artifact.archive_download_url, headers=github_headers, timeout=30
)
zip_file = Path(settings.input_path)
zip_file.write_bytes(file_response.content)
logging.info("Finished")

7
.github/actions/people/Dockerfile vendored Normal file
View File

@@ -0,0 +1,7 @@
FROM python:3.7
RUN pip install httpx PyGithub "pydantic==1.5.1" "pyyaml>=5.3.1,<6.0.0"
COPY ./app /app
CMD ["python", "/app/main.py"]

13
.github/actions/people/action.yml vendored Normal file
View File

@@ -0,0 +1,13 @@
name: "Generate FastAPI People"
description: "Generate the data for the FastAPI People page"
author: "Sebastián Ramírez <tiangolo@gmail.com>"
inputs:
token:
description: 'User token, to read the GitHub API. Can be passed in using {{ secrets.ACTION_TOKEN }}'
required: true
standard_token:
description: 'Default GitHub Action token, used for the PR. Can be passed in using {{ secrets.GITHUB_TOKEN }}'
required: true
runs:
using: 'docker'
image: 'Dockerfile'

518
.github/actions/people/app/main.py vendored Normal file
View File

@@ -0,0 +1,518 @@
import logging
import subprocess
import sys
from collections import Counter
from datetime import datetime, timedelta, timezone
from pathlib import Path
from typing import Container, Dict, List, Optional, Set
import httpx
import yaml
from github import Github
from pydantic import BaseModel, BaseSettings, SecretStr
github_graphql_url = "https://api.github.com/graphql"
issues_query = """
query Q($after: String) {
repository(name: "fastapi", owner: "tiangolo") {
issues(first: 100, after: $after) {
edges {
cursor
node {
number
author {
login
avatarUrl
url
}
title
createdAt
state
comments(first: 100) {
nodes {
createdAt
author {
login
avatarUrl
url
}
}
}
}
}
}
}
}
"""
prs_query = """
query Q($after: String) {
repository(name: "fastapi", owner: "tiangolo") {
pullRequests(first: 100, after: $after) {
edges {
cursor
node {
number
labels(first: 100) {
nodes {
name
}
}
author {
login
avatarUrl
url
}
title
createdAt
state
comments(first: 100) {
nodes {
createdAt
author {
login
avatarUrl
url
}
}
}
reviews(first:100) {
nodes {
author {
login
avatarUrl
url
}
state
}
}
}
}
}
}
}
"""
sponsors_query = """
query Q($after: String) {
user(login: "tiangolo") {
sponsorshipsAsMaintainer(first: 100, after: $after) {
edges {
cursor
node {
sponsorEntity {
... on Organization {
login
avatarUrl
url
}
... on User {
login
avatarUrl
url
}
}
tier {
name
monthlyPriceInDollars
}
}
}
}
}
}
"""
class Author(BaseModel):
login: str
avatarUrl: str
url: str
class CommentsNode(BaseModel):
createdAt: datetime
author: Optional[Author] = None
class Comments(BaseModel):
nodes: List[CommentsNode]
class IssuesNode(BaseModel):
number: int
author: Optional[Author] = None
title: str
createdAt: datetime
state: str
comments: Comments
class IssuesEdge(BaseModel):
cursor: str
node: IssuesNode
class Issues(BaseModel):
edges: List[IssuesEdge]
class IssuesRepository(BaseModel):
issues: Issues
class IssuesResponseData(BaseModel):
repository: IssuesRepository
class IssuesResponse(BaseModel):
data: IssuesResponseData
class LabelNode(BaseModel):
name: str
class Labels(BaseModel):
nodes: List[LabelNode]
class ReviewNode(BaseModel):
author: Optional[Author] = None
state: str
class Reviews(BaseModel):
nodes: List[ReviewNode]
class PullRequestNode(BaseModel):
number: int
labels: Labels
author: Optional[Author] = None
title: str
createdAt: datetime
state: str
comments: Comments
reviews: Reviews
class PullRequestEdge(BaseModel):
cursor: str
node: PullRequestNode
class PullRequests(BaseModel):
edges: List[PullRequestEdge]
class PRsRepository(BaseModel):
pullRequests: PullRequests
class PRsResponseData(BaseModel):
repository: PRsRepository
class PRsResponse(BaseModel):
data: PRsResponseData
class SponsorEntity(BaseModel):
login: str
avatarUrl: str
url: str
class Tier(BaseModel):
name: str
monthlyPriceInDollars: float
class SponsorshipAsMaintainerNode(BaseModel):
sponsorEntity: SponsorEntity
tier: Tier
class SponsorshipAsMaintainerEdge(BaseModel):
cursor: str
node: SponsorshipAsMaintainerNode
class SponsorshipAsMaintainer(BaseModel):
edges: List[SponsorshipAsMaintainerEdge]
class SponsorsUser(BaseModel):
sponsorshipsAsMaintainer: SponsorshipAsMaintainer
class SponsorsResponseData(BaseModel):
user: SponsorsUser
class SponsorsResponse(BaseModel):
data: SponsorsResponseData
class Settings(BaseSettings):
input_token: SecretStr
input_standard_token: SecretStr
github_repository: str
def get_graphql_response(
*, settings: Settings, query: str, after: Optional[str] = None
):
headers = {"Authorization": f"token {settings.input_token.get_secret_value()}"}
variables = {"after": after}
response = httpx.post(
github_graphql_url,
headers=headers,
json={"query": query, "variables": variables, "operationName": "Q"},
)
if not response.status_code == 200:
logging.error(f"Response was not 200, after: {after}")
logging.error(response.text)
raise RuntimeError(response.text)
data = response.json()
return data
def get_graphql_issue_edges(*, settings: Settings, after: Optional[str] = None):
data = get_graphql_response(settings=settings, query=issues_query, after=after)
graphql_response = IssuesResponse.parse_obj(data)
return graphql_response.data.repository.issues.edges
def get_graphql_pr_edges(*, settings: Settings, after: Optional[str] = None):
data = get_graphql_response(settings=settings, query=prs_query, after=after)
graphql_response = PRsResponse.parse_obj(data)
return graphql_response.data.repository.pullRequests.edges
def get_graphql_sponsor_edges(*, settings: Settings, after: Optional[str] = None):
data = get_graphql_response(settings=settings, query=sponsors_query, after=after)
graphql_response = SponsorsResponse.parse_obj(data)
return graphql_response.data.user.sponsorshipsAsMaintainer.edges
def get_experts(settings: Settings):
issue_nodes: List[IssuesNode] = []
issue_edges = get_graphql_issue_edges(settings=settings)
while issue_edges:
for edge in issue_edges:
issue_nodes.append(edge.node)
last_edge = issue_edges[-1]
issue_edges = get_graphql_issue_edges(settings=settings, after=last_edge.cursor)
commentors = Counter()
last_month_commentors = Counter()
authors: Dict[str, Author] = {}
now = datetime.now(tz=timezone.utc)
one_month_ago = now - timedelta(days=30)
for issue in issue_nodes:
issue_author_name = None
if issue.author:
authors[issue.author.login] = issue.author
issue_author_name = issue.author.login
issue_commentors = set()
for comment in issue.comments.nodes:
if comment.author:
authors[comment.author.login] = comment.author
if comment.author.login == issue_author_name:
continue
issue_commentors.add(comment.author.login)
for author_name in issue_commentors:
commentors[author_name] += 1
if issue.createdAt > one_month_ago:
last_month_commentors[author_name] += 1
return commentors, last_month_commentors, authors
def get_contributors(settings: Settings):
pr_nodes: List[PullRequestNode] = []
pr_edges = get_graphql_pr_edges(settings=settings)
while pr_edges:
for edge in pr_edges:
pr_nodes.append(edge.node)
last_edge = pr_edges[-1]
pr_edges = get_graphql_pr_edges(settings=settings, after=last_edge.cursor)
contributors = Counter()
commentors = Counter()
reviewers = Counter()
authors: Dict[str, Author] = {}
for pr in pr_nodes:
author_name = None
if pr.author:
authors[pr.author.login] = pr.author
author_name = pr.author.login
pr_commentors: Set[str] = set()
pr_reviewers: Set[str] = set()
for comment in pr.comments.nodes:
if comment.author:
authors[comment.author.login] = comment.author
if comment.author.login == author_name:
continue
pr_commentors.add(comment.author.login)
for author_name in pr_commentors:
commentors[author_name] += 1
for review in pr.reviews.nodes:
if review.author:
authors[review.author.login] = review.author
pr_reviewers.add(review.author.login)
for reviewer in pr_reviewers:
reviewers[reviewer] += 1
if pr.state == "MERGED" and pr.author:
contributors[pr.author.login] += 1
return contributors, commentors, reviewers, authors
def get_individual_sponsors(settings: Settings, max_individual_sponsor: int = 5):
nodes: List[SponsorshipAsMaintainerNode] = []
edges = get_graphql_sponsor_edges(settings=settings)
while edges:
for edge in edges:
nodes.append(edge.node)
last_edge = edges[-1]
edges = get_graphql_sponsor_edges(settings=settings, after=last_edge.cursor)
entities: Dict[str, SponsorEntity] = {}
for node in nodes:
if node.tier.monthlyPriceInDollars > max_individual_sponsor:
continue
entities[node.sponsorEntity.login] = node.sponsorEntity
return entities
def get_top_users(
*,
counter: Counter,
min_count: int,
authors: Dict[str, Author],
skip_users: Container[str],
):
users = []
for commentor, count in counter.most_common(50):
if commentor in skip_users:
continue
if count >= min_count:
author = authors[commentor]
users.append(
{
"login": commentor,
"count": count,
"avatarUrl": author.avatarUrl,
"url": author.url,
}
)
return users
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
settings = Settings()
logging.info(f"Using config: {settings.json()}")
g = Github(settings.input_standard_token.get_secret_value())
repo = g.get_repo(settings.github_repository)
issue_commentors, issue_last_month_commentors, issue_authors = get_experts(
settings=settings
)
contributors, pr_commentors, reviewers, pr_authors = get_contributors(
settings=settings
)
authors = {**issue_authors, **pr_authors}
maintainers_logins = {"tiangolo"}
bot_names = {"codecov", "github-actions"}
maintainers = []
for login in maintainers_logins:
user = authors[login]
maintainers.append(
{
"login": login,
"answers": issue_commentors[login],
"prs": contributors[login],
"avatarUrl": user.avatarUrl,
"url": user.url,
}
)
min_count_expert = 10
min_count_last_month = 3
min_count_contributor = 4
min_count_reviewer = 4
skip_users = maintainers_logins | bot_names
experts = get_top_users(
counter=issue_commentors,
min_count=min_count_expert,
authors=authors,
skip_users=skip_users,
)
last_month_active = get_top_users(
counter=issue_last_month_commentors,
min_count=min_count_last_month,
authors=authors,
skip_users=skip_users,
)
top_contributors = get_top_users(
counter=contributors,
min_count=min_count_contributor,
authors=authors,
skip_users=skip_users,
)
top_reviewers = get_top_users(
counter=reviewers,
min_count=min_count_reviewer,
authors=authors,
skip_users=skip_users,
)
sponsors_by_login = get_individual_sponsors(settings=settings)
sponsors = []
for login, sponsor in sponsors_by_login.items():
sponsors.append(
{"login": login, "avatarUrl": sponsor.avatarUrl, "url": sponsor.url}
)
people = {
"maintainers": maintainers,
"experts": experts,
"last_month_active": last_month_active,
"top_contributors": top_contributors,
"top_reviewers": top_reviewers,
"sponsors": sponsors,
}
people_path = Path("./docs/en/data/people.yml")
people_old_content = people_path.read_text(encoding="utf-8")
new_content = yaml.dump(people, sort_keys=False, width=200, allow_unicode=True)
if people_old_content == new_content:
logging.info("The FastAPI People data hasn't changed, finishing.")
sys.exit(0)
people_path.write_text(new_content, encoding="utf-8")
logging.info("Setting up GitHub Actions git user")
subprocess.run(["git", "config", "user.name", "github-actions"], check=True)
subprocess.run(
["git", "config", "user.email", "github-actions@github.com"], check=True
)
branch_name = "fastapi-people"
logging.info(f"Creating a new branch {branch_name}")
subprocess.run(["git", "checkout", "-b", branch_name], check=True)
logging.info("Adding updated file")
subprocess.run(["git", "add", str(people_path)], check=True)
logging.info("Committing updated file")
message = "👥 Update FastAPI People"
result = subprocess.run(["git", "commit", "-m", message], check=True)
logging.info("Pushing branch")
subprocess.run(["git", "push", "origin", branch_name], check=True)
logging.info("Creating PR")
pr = repo.create_pull(title=message, body=message, base="master", head=branch_name)
logging.info(f"Created PR: {pr.number}")
logging.info("Finished")

View File

@@ -20,15 +20,16 @@ jobs:
run: python3.7 -m pip install flit
- name: Install docs extras
run: python3.7 -m flit install --extras doc
- name: Install Material for MkDocs Insiders
if: github.event.pull_request.head.repo.fork == false
run: pip install git+https://${{ secrets.ACTIONS_TOKEN }}@github.com/squidfunk/mkdocs-material-insiders.git
- name: Build Docs
run: python3.7 ./scripts/docs.py build-all
- name: Zip docs
if: github.event_name == 'pull_request'
run: bash ./scripts/zip-docs.sh
- uses: actions/upload-artifact@v2
if: github.event_name == 'pull_request'
with:
name: docs-zip-${{ github.event.pull_request.head.sha }}
name: docs-zip
path: ./docs.zip
- name: Deploy to Netlify
uses: nwtgck/actions-netlify@v1.1.5

13
.github/workflows/label-approved.yml vendored Normal file
View File

@@ -0,0 +1,13 @@
name: Label Approved
on:
schedule:
- cron: "0 12 * * *"
jobs:
label-approved:
runs-on: ubuntu-latest
steps:
- uses: docker://tiangolo/label-approved:0.0.2
with:
token: ${{ secrets.GITHUB_TOKEN }}

25
.github/workflows/latest-changes.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
name: Latest Changes
on:
pull_request_target:
branches:
- master
types:
- closed
workflow_dispatch:
inputs:
number:
description: PR number
required: true
jobs:
latest-changes:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: docker://tiangolo/latest-changes:0.0.3
with:
token: ${{ secrets.GITHUB_TOKEN }}
latest_changes_file: docs/en/docs/release-notes.md
latest_changes_header: '## Latest Changes\n\n'
debug_logs: true

16
.github/workflows/people.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
name: FastAPI People
on:
schedule:
- cron: "0 14 1 * *"
workflow_dispatch:
jobs:
fastapi-people:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/people
with:
token: ${{ secrets.ACTIONS_TOKEN }}
standard_token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,14 +0,0 @@
name: Label approved pull requests
on: pull_request_review
jobs:
labelWhenApproved:
name: Label when approved
runs-on: ubuntu-latest
steps:
- name: Label when approved
uses: pullreminders/label-when-approved-action@v1.0.7
env:
APPROVALS: "2"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ADD_LABEL: "approved-2"
REMOVE_LABEL: "awaiting%20review"

View File

@@ -1,29 +1,28 @@
name: Preview Docs
on:
workflow_dispatch:
inputs:
pr:
description: Pull Request number
required: true
name:
description: Artifact name for zip file with docs
required: true
commit:
description: Commit SHA hash
required: true
workflow_run:
workflows:
- Build Docs
types:
- completed
jobs:
deploy:
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/get-artifact
- name: Download Artifact Docs
uses: dawidd6/action-download-artifact@v2.9.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
name: ${{ github.event.inputs.name }}
path: ./archive.zip
github_token: ${{ secrets.GITHUB_TOKEN }}
workflow: build-docs.yml
run_id: ${{ github.event.workflow_run.id }}
name: docs-zip
- name: Unzip docs
run: bash ./scripts/unzip-docs.sh
run: |
rm -rf ./site
unzip docs.zip
rm -f docs.zip
- name: Deploy to Netlify
id: netlify
uses: nwtgck/actions-netlify@v1.1.5
@@ -36,9 +35,7 @@ jobs:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
- name: Comment Deploy
env:
PR: "${{ github.event.inputs.pr }}"
DEPLOY_URL: "${{ steps.netlify.outputs.deploy-url }}"
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
COMMIT: "${{ github.event.inputs.commit }}"
run: bash ./scripts/docs-comment-deploy.sh
uses: ./.github/actions/comment-docs-preview-in-pr
with:
token: ${{ secrets.GITHUB_TOKEN }}
deploy_url: "${{ steps.netlify.outputs.deploy-url }}"

View File

@@ -31,9 +31,9 @@ jobs:
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- name: Notify
env:
GITTER_TOKEN: ${{ secrets.GITTER_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ github.event.release.name }}
run: bash scripts/notify.sh
# - name: Notify
# env:
# GITTER_TOKEN: ${{ secrets.GITTER_TOKEN }}
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# TAG: ${{ github.event.release.name }}
# run: bash scripts/notify.sh

View File

@@ -1,13 +0,0 @@
name: Watch Docs Previews
on:
schedule:
- cron: "0 * * * *"
jobs:
deploy:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/watch-previews
with:
token: ${{ secrets.ACTIONS_TOKEN }}

View File

@@ -14,9 +14,6 @@
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Package version">
</a>
<a href="https://gitter.im/tiangolo/fastapi?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge" target="_blank">
<img src="https://badges.gitter.im/tiangolo/fastapi.svg" alt="Join the chat at https://gitter.im/tiangolo/fastapi">
</a>
</p>
---
@@ -39,10 +36,20 @@ The key features are:
* **Easy**: Designed to be easy to use and learn. Less time reading docs.
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
* **Robust**: Get production-ready code. With automatic interactive documentation.
* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (previously known as Swagger) and <a href="http://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (previously known as Swagger) and <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
<small>* estimation based on tests on an internal development team, building production applications.</small>
## Gold Sponsors
<!-- sponsors -->
<a href="https://www.deta.sh/?ref=fastapi" target="_blank" title="The launchpad for all your (team's) ideas"><img src="https://fastapi.tiangolo.com/img/sponsors/deta.svg"></a>
<!-- /sponsors -->
<a href="https://fastapi.tiangolo.com/fastapi-people/#sponsors" class="external-link" target="_blank">Other sponsors</a>
## Opinions
"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._"
@@ -71,7 +78,7 @@ The key features are:
"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._"
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="http://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
---
@@ -112,7 +119,7 @@ $ pip install fastapi
</div>
You will also need an ASGI server, for production such as <a href="http://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> or <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>.
You will also need an ASGI server, for production such as <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> or <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>.
<div class="termy">
@@ -153,7 +160,7 @@ def read_item(item_id: int, q: Optional[str] = None):
If your code uses `async` / `await`, use `async def`:
```Python hl_lines="9 14"
```Python hl_lines="9 14"
from typing import Optional
from fastapi import FastAPI
@@ -245,7 +252,7 @@ Now modify the file `main.py` to receive a body from a `PUT` request.
Declare the body using standard Python types, thanks to Pydantic.
```Python hl_lines="4 9 10 11 12 25 26 27"
```Python hl_lines="4 9-12 25-27"
from typing import Optional
from fastapi import FastAPI
@@ -428,9 +435,9 @@ Used by Pydantic:
Used by Starlette:
* <a href="http://docs.python-requests.org" target="_blank"><code>requests</code></a> - Required if you want to use the `TestClient`.
* <a href="https://requests.readthedocs.io" target="_blank"><code>requests</code></a> - Required if you want to use the `TestClient`.
* <a href="https://github.com/Tinche/aiofiles" target="_blank"><code>aiofiles</code></a> - Required if you want to use `FileResponse` or `StaticFiles`.
* <a href="http://jinja.pocoo.org" target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`.
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Required for `SessionMiddleware` support.
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Required for Starlette's `SchemaGenerator` support (you probably don't need it with FastAPI).
@@ -439,7 +446,7 @@ Used by Starlette:
Used by FastAPI / Starlette:
* <a href="http://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - for the server that loads and serves your application.
* <a href="https://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - for the server that loads and serves your application.
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - Required if you want to use `ORJSONResponse`.
You can install all of these with `pip install fastapi[all]`.

View File

@@ -16,9 +16,9 @@ articles:
title: Introduction to the fastapi python framework
author_link: https://dev.to/errietta
author: Errieta Kostala
- link: http://nickc1.github.io/api,/scikit-learn/2019/01/10/scikit-fastapi.html
- link: https://nickc1.github.io/api,/scikit-learn/2019/01/10/scikit-fastapi.html
title: "FastAPI and Scikit-Learn: Easily Deploy Models"
author_link: http://nickc1.github.io/
author_link: https://nickc1.github.io/
author: Nick Cortale
- link: https://medium.com/data-rebels/fastapi-authentication-revisited-enabling-api-key-authentication-122dc5975680
title: "FastAPI authentication revisited: Enabling API key authentication"
@@ -136,6 +136,18 @@ articles:
title: Build And Host Fast Data Science Applications Using FastAPI
author_link: https://medium.com/@farhadmalik
author: Farhad Malik
- link: https://medium.com/@gabbyprecious2000/creating-a-crud-app-with-fastapi-part-one-7c049292ad37
title: Creating a CRUD App with FastAPI (Part one)
author_link: https://medium.com/@gabbyprecious2000
author: Precious Ndubueze
- link: https://julienharbulot.com/notification-server.html
title: HTTP server to display desktop notifications
author_link: https://julienharbulot.com/
author: Julien Harbulot
- link: https://guitton.co/posts/fastapi-monitoring/
title: How to monitor your FastAPI service
author_link: https://twitter.com/louis_guitton
author: Louis Guitton
japanese:
- link: https://qiita.com/mtitg/items/47770e9a562dd150631d
title: FastAPIDB接続してCRUDするPython製APIサーバーを構築

368
docs/en/data/people.yml Normal file
View File

@@ -0,0 +1,368 @@
maintainers:
- login: tiangolo
answers: 979
prs: 189
avatarUrl: https://avatars1.githubusercontent.com/u/1326112?u=05f95ca7fdead36edd9c86be46b4ef6c3c71f876&v=4
url: https://github.com/tiangolo
experts:
- login: dmontagu
count: 262
avatarUrl: https://avatars2.githubusercontent.com/u/35119617?u=58ed2a45798a4339700e2f62b2e12e6e54bf0396&v=4
url: https://github.com/dmontagu
- login: euri10
count: 166
avatarUrl: https://avatars3.githubusercontent.com/u/1104190?u=ffd411da5d3b7ad3aa18261317f7ddc76f763c33&v=4
url: https://github.com/euri10
- login: phy25
count: 129
avatarUrl: https://avatars0.githubusercontent.com/u/331403?v=4
url: https://github.com/phy25
- login: Kludex
count: 104
avatarUrl: https://avatars1.githubusercontent.com/u/7353520?u=cf8455cb899806b774a3a71073f88583adec99f6&v=4
url: https://github.com/Kludex
- login: ycd
count: 61
avatarUrl: https://avatars2.githubusercontent.com/u/62724709?u=496a800351ea1009678e40b26288a2a6c0dfa8bd&v=4
url: https://github.com/ycd
- login: sm-Fifteen
count: 39
avatarUrl: https://avatars0.githubusercontent.com/u/516999?u=437c0c5038558c67e887ccd863c1ba0f846c03da&v=4
url: https://github.com/sm-Fifteen
- login: ArcLightSlavik
count: 35
avatarUrl: https://avatars3.githubusercontent.com/u/31127044?u=b81d0c33b056152513fb14749a9fe00f39887a8e&v=4
url: https://github.com/ArcLightSlavik
- login: prostomarkeloff
count: 33
avatarUrl: https://avatars3.githubusercontent.com/u/28061158?u=72309cc1f2e04e40fa38b29969cb4e9d3f722e7b&v=4
url: https://github.com/prostomarkeloff
- login: Mause
count: 32
avatarUrl: https://avatars2.githubusercontent.com/u/1405026?v=4
url: https://github.com/Mause
- login: wshayes
count: 29
avatarUrl: https://avatars2.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
url: https://github.com/wshayes
- login: dbanty
count: 25
avatarUrl: https://avatars2.githubusercontent.com/u/43723790?u=0cf33e4f40efc2ea206a1189fd63a11344eb88ed&v=4
url: https://github.com/dbanty
- login: SirTelemak
count: 23
avatarUrl: https://avatars1.githubusercontent.com/u/9435877?u=719327b7d2c4c62212456d771bfa7c6b8dbb9eac&v=4
url: https://github.com/SirTelemak
- login: nsidnev
count: 22
avatarUrl: https://avatars0.githubusercontent.com/u/22559461?u=a9cc3238217e21dc8796a1a500f01b722adb082c&v=4
url: https://github.com/nsidnev
- login: chris-allnutt
count: 21
avatarUrl: https://avatars0.githubusercontent.com/u/565544?v=4
url: https://github.com/chris-allnutt
- login: Dustyposa
count: 21
avatarUrl: https://avatars0.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4
url: https://github.com/Dustyposa
- login: acnebs
count: 19
avatarUrl: https://avatars2.githubusercontent.com/u/9054108?u=bfd127b3e6200f4d00afd714f0fc95c2512df19b&v=4
url: https://github.com/acnebs
- login: retnikt
count: 19
avatarUrl: https://avatars1.githubusercontent.com/u/24581770?v=4
url: https://github.com/retnikt
- login: raphaelauv
count: 18
avatarUrl: https://avatars3.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
url: https://github.com/raphaelauv
- login: jorgerpo
count: 17
avatarUrl: https://avatars1.githubusercontent.com/u/12537771?u=7444d20019198e34911082780cc7ad73f2b97cb3&v=4
url: https://github.com/jorgerpo
- login: includeamin
count: 17
avatarUrl: https://avatars1.githubusercontent.com/u/11836741?u=8bd5ef7e62fe6a82055e33c4c0e0a7879ff8cfb6&v=4
url: https://github.com/includeamin
- login: Slyfoxy
count: 17
avatarUrl: https://avatars1.githubusercontent.com/u/28262306?u=66ee21316275ef356081c2efc4ed7a4572e690dc&v=4
url: https://github.com/Slyfoxy
- login: haizaar
count: 13
avatarUrl: https://avatars3.githubusercontent.com/u/58201?u=4f1f9843d69433ca0d380d95146cfe119e5fdac4&v=4
url: https://github.com/haizaar
- login: zamiramir
count: 11
avatarUrl: https://avatars1.githubusercontent.com/u/40475662?u=e58ef61034e8d0d6a312cc956fb09b9c3332b449&v=4
url: https://github.com/zamiramir
- login: stefanondisponibile
count: 10
avatarUrl: https://avatars1.githubusercontent.com/u/20441825?u=ee1e59446b98f8ec2363caeda4c17164d0d9cc7d&v=4
url: https://github.com/stefanondisponibile
last_month_active:
- login: ycd
count: 19
avatarUrl: https://avatars2.githubusercontent.com/u/62724709?u=496a800351ea1009678e40b26288a2a6c0dfa8bd&v=4
url: https://github.com/ycd
- login: Mause
count: 18
avatarUrl: https://avatars2.githubusercontent.com/u/1405026?v=4
url: https://github.com/Mause
- login: Kludex
count: 11
avatarUrl: https://avatars1.githubusercontent.com/u/7353520?u=cf8455cb899806b774a3a71073f88583adec99f6&v=4
url: https://github.com/Kludex
- login: includeamin
count: 11
avatarUrl: https://avatars1.githubusercontent.com/u/11836741?u=8bd5ef7e62fe6a82055e33c4c0e0a7879ff8cfb6&v=4
url: https://github.com/includeamin
- login: eseglem
count: 7
avatarUrl: https://avatars3.githubusercontent.com/u/5920492?u=208d419cf667b8ac594c82a8db01932c7e50d057&v=4
url: https://github.com/eseglem
- login: ArcLightSlavik
count: 5
avatarUrl: https://avatars3.githubusercontent.com/u/31127044?u=b81d0c33b056152513fb14749a9fe00f39887a8e&v=4
url: https://github.com/ArcLightSlavik
- login: SirTelemak
count: 4
avatarUrl: https://avatars1.githubusercontent.com/u/9435877?u=719327b7d2c4c62212456d771bfa7c6b8dbb9eac&v=4
url: https://github.com/SirTelemak
- login: clmno
count: 3
avatarUrl: https://avatars3.githubusercontent.com/u/17064666?v=4
url: https://github.com/clmno
top_contributors:
- login: dmontagu
count: 16
avatarUrl: https://avatars2.githubusercontent.com/u/35119617?u=58ed2a45798a4339700e2f62b2e12e6e54bf0396&v=4
url: https://github.com/dmontagu
- login: waynerv
count: 16
avatarUrl: https://avatars3.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
url: https://github.com/waynerv
- login: euri10
count: 13
avatarUrl: https://avatars3.githubusercontent.com/u/1104190?u=ffd411da5d3b7ad3aa18261317f7ddc76f763c33&v=4
url: https://github.com/euri10
- login: tokusumi
count: 10
avatarUrl: https://avatars0.githubusercontent.com/u/41147016?u=55010621aece725aa702270b54fed829b6a1fe60&v=4
url: https://github.com/tokusumi
- login: mariacamilagl
count: 8
avatarUrl: https://avatars2.githubusercontent.com/u/11489395?u=4adb6986bf3debfc2b8216ae701f2bd47d73da7d&v=4
url: https://github.com/mariacamilagl
- login: Serrones
count: 6
avatarUrl: https://avatars3.githubusercontent.com/u/22691749?u=4795b880e13ca33a73e52fc0ef7dc9c60c8fce47&v=4
url: https://github.com/Serrones
- login: wshayes
count: 5
avatarUrl: https://avatars2.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
url: https://github.com/wshayes
- login: jekirl
count: 4
avatarUrl: https://avatars3.githubusercontent.com/u/2546697?v=4
url: https://github.com/jekirl
top_reviewers:
- login: Kludex
count: 53
avatarUrl: https://avatars1.githubusercontent.com/u/7353520?u=cf8455cb899806b774a3a71073f88583adec99f6&v=4
url: https://github.com/Kludex
- login: tokusumi
count: 40
avatarUrl: https://avatars0.githubusercontent.com/u/41147016?u=55010621aece725aa702270b54fed829b6a1fe60&v=4
url: https://github.com/tokusumi
- login: dmontagu
count: 23
avatarUrl: https://avatars2.githubusercontent.com/u/35119617?u=58ed2a45798a4339700e2f62b2e12e6e54bf0396&v=4
url: https://github.com/dmontagu
- login: ycd
count: 17
avatarUrl: https://avatars2.githubusercontent.com/u/62724709?u=496a800351ea1009678e40b26288a2a6c0dfa8bd&v=4
url: https://github.com/ycd
- login: AdrianDeAnda
count: 16
avatarUrl: https://avatars0.githubusercontent.com/u/1024932?u=bb7f8a0d6c9de4e9d0320a9f271210206e202250&v=4
url: https://github.com/AdrianDeAnda
- login: SwftAlpc
count: 16
avatarUrl: https://avatars1.githubusercontent.com/u/52768429?u=6a3aa15277406520ad37f6236e89466ed44bc5b8&v=4
url: https://github.com/SwftAlpc
- login: cassiobotaro
count: 14
avatarUrl: https://avatars2.githubusercontent.com/u/3127847?u=b0a652331da17efeb85cd6e3a4969182e5004804&v=4
url: https://github.com/cassiobotaro
- login: Laineyzhang55
count: 12
avatarUrl: https://avatars0.githubusercontent.com/u/59285379?v=4
url: https://github.com/Laineyzhang55
- login: yanever
count: 11
avatarUrl: https://avatars2.githubusercontent.com/u/21978760?v=4
url: https://github.com/yanever
- login: waynerv
count: 10
avatarUrl: https://avatars3.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
url: https://github.com/waynerv
- login: mariacamilagl
count: 10
avatarUrl: https://avatars2.githubusercontent.com/u/11489395?u=4adb6986bf3debfc2b8216ae701f2bd47d73da7d&v=4
url: https://github.com/mariacamilagl
- login: Attsun1031
count: 10
avatarUrl: https://avatars2.githubusercontent.com/u/1175560?v=4
url: https://github.com/Attsun1031
- login: RunningIkkyu
count: 9
avatarUrl: https://avatars0.githubusercontent.com/u/31848542?u=706e1ee3f248245f2d68b976d149d06fd5a2010d&v=4
url: https://github.com/RunningIkkyu
- login: komtaki
count: 9
avatarUrl: https://avatars1.githubusercontent.com/u/39375566?v=4
url: https://github.com/komtaki
- login: Serrones
count: 7
avatarUrl: https://avatars3.githubusercontent.com/u/22691749?u=4795b880e13ca33a73e52fc0ef7dc9c60c8fce47&v=4
url: https://github.com/Serrones
- login: ryuckel
count: 7
avatarUrl: https://avatars1.githubusercontent.com/u/36391432?u=094eec0cfddd5013f76f31e55e56147d78b19553&v=4
url: https://github.com/ryuckel
- login: MashhadiNima
count: 5
avatarUrl: https://avatars0.githubusercontent.com/u/49960770?u=e39b11d47188744ee07b2a1c7ce1a1bdf3c80760&v=4
url: https://github.com/MashhadiNima
- login: euri10
count: 4
avatarUrl: https://avatars3.githubusercontent.com/u/1104190?u=ffd411da5d3b7ad3aa18261317f7ddc76f763c33&v=4
url: https://github.com/euri10
- login: rkbeatss
count: 4
avatarUrl: https://avatars0.githubusercontent.com/u/23391143?u=56ab6bff50be950fa8cae5cf736f2ae66e319ff3&v=4
url: https://github.com/rkbeatss
- login: raphaelauv
count: 4
avatarUrl: https://avatars3.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
url: https://github.com/raphaelauv
sponsors:
- login: samuelcolvin
avatarUrl: https://avatars3.githubusercontent.com/u/4039449?u=807390ba9cfe23906c3bf8a0d56aaca3cf2bfa0d&v=4
url: https://github.com/samuelcolvin
- login: mkeen
avatarUrl: https://avatars3.githubusercontent.com/u/38221?u=03e076e08a10a4de0d48a348f1aab0223c5cf24a&v=4
url: https://github.com/mkeen
- login: wshayes
avatarUrl: https://avatars2.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
url: https://github.com/wshayes
- login: ltieman
avatarUrl: https://avatars1.githubusercontent.com/u/1084689?u=c9bf77f5e57f98b49694870219b9bd9d1cc862e7&v=4
url: https://github.com/ltieman
- login: mrmattwright
avatarUrl: https://avatars3.githubusercontent.com/u/1277725?v=4
url: https://github.com/mrmattwright
- login: timdrijvers
avatarUrl: https://avatars1.githubusercontent.com/u/1694939?v=4
url: https://github.com/timdrijvers
- login: abdelhai
avatarUrl: https://avatars3.githubusercontent.com/u/1752577?u=8f8f2bce75f3ab68188cea2b5da37c784197acd8&v=4
url: https://github.com/abdelhai
- login: ddahan
avatarUrl: https://avatars0.githubusercontent.com/u/1933516?u=4068dc3c5db5d3605116c4f5df6deb9fee324c33&v=4
url: https://github.com/ddahan
- login: cbonoz
avatarUrl: https://avatars0.githubusercontent.com/u/2351087?u=fd3e8030b2cc9fbfbb54a65e9890c548a016f58b&v=4
url: https://github.com/cbonoz
- login: mrgnw
avatarUrl: https://avatars3.githubusercontent.com/u/2504532?u=7ec43837a6d0afa80f96f0788744ea6341b89f97&v=4
url: https://github.com/mrgnw
- login: paul121
avatarUrl: https://avatars2.githubusercontent.com/u/3116995?u=6e2d8691cc345e63ee02e4eb4d7cef82b1fcbedc&v=4
url: https://github.com/paul121
- login: andre1sk
avatarUrl: https://avatars1.githubusercontent.com/u/3148093?v=4
url: https://github.com/andre1sk
- login: igorcorrea
avatarUrl: https://avatars0.githubusercontent.com/u/3438238?u=c57605077c31a8f7b2341fc4912507f91b4a5621&v=4
url: https://github.com/igorcorrea
- login: pawamoy
avatarUrl: https://avatars2.githubusercontent.com/u/3999221?u=b030e4c89df2f3a36bc4710b925bdeb6745c9856&v=4
url: https://github.com/pawamoy
- login: p141592
avatarUrl: https://avatars3.githubusercontent.com/u/5256328?u=7f9fdf3329bf90017cff00c8a78781bd7a2b48aa&v=4
url: https://github.com/p141592
- login: fabboe
avatarUrl: https://avatars3.githubusercontent.com/u/7251331?v=4
url: https://github.com/fabboe
- login: Shackelford-Arden
avatarUrl: https://avatars0.githubusercontent.com/u/7362263?v=4
url: https://github.com/Shackelford-Arden
- login: macleodmac
avatarUrl: https://avatars2.githubusercontent.com/u/8996312?u=e39c68c3e0b1d264dcba4850134a291680f46355&v=4
url: https://github.com/macleodmac
- login: cristeaadrian
avatarUrl: https://avatars0.githubusercontent.com/u/9112724?u=76099d546d6ee44b3ad7269773ecb916590c6a36&v=4
url: https://github.com/cristeaadrian
- login: otivvormes
avatarUrl: https://avatars2.githubusercontent.com/u/11317418?u=6de1edefb6afd0108c0ad2816bd6efc4464a9c44&v=4
url: https://github.com/otivvormes
- login: iambobmae
avatarUrl: https://avatars2.githubusercontent.com/u/12390270?u=c9a35c2ee5092a9b4135ebb1f91b7f521c467031&v=4
url: https://github.com/iambobmae
- login: Cozmo25
avatarUrl: https://avatars1.githubusercontent.com/u/12619962?u=679dcd6785121e14f6254e9dd0961baf3b1fef5d&v=4
url: https://github.com/Cozmo25
- login: la-mar
avatarUrl: https://avatars1.githubusercontent.com/u/16618300?u=7755c0521d2bb0d704f35a51464b15c1e2e6c4da&v=4
url: https://github.com/la-mar
- login: robintully
avatarUrl: https://avatars2.githubusercontent.com/u/17059673?u=862b9bb01513f5acd30df97433cb97a24dbfb772&v=4
url: https://github.com/robintully
- login: Duval23
avatarUrl: https://avatars1.githubusercontent.com/u/17622958?v=4
url: https://github.com/Duval23
- login: wedwardbeck
avatarUrl: https://avatars3.githubusercontent.com/u/19333237?u=1de4ae2bf8d59eb4c013f21d863cbe0f2010575f&v=4
url: https://github.com/wedwardbeck
- login: linusg
avatarUrl: https://avatars3.githubusercontent.com/u/19366641?u=125e390abef8fff3b3b0d370c369cba5d7fd4c67&v=4
url: https://github.com/linusg
- login: SebastianLuebke
avatarUrl: https://avatars3.githubusercontent.com/u/21161532?u=ba033c1bf6851b874cfa05a8a824b9f1ff434c37&v=4
url: https://github.com/SebastianLuebke
- login: raminsj13
avatarUrl: https://avatars2.githubusercontent.com/u/24259406?u=d51f2a526312ebba150a06936ed187ca0727d329&v=4
url: https://github.com/raminsj13
- login: mertguvencli
avatarUrl: https://avatars3.githubusercontent.com/u/29762151?u=16a906d90df96c8cff9ea131a575c4bc171b1523&v=4
url: https://github.com/mertguvencli
- login: orihomie
avatarUrl: https://avatars3.githubusercontent.com/u/29889683?u=6bc2135a52fcb3a49e69e7d50190796618185fda&v=4
url: https://github.com/orihomie
- login: dcooper01
avatarUrl: https://avatars2.githubusercontent.com/u/32238294?u=2a83c78b7f2a5f97beeede0b604bbe44cd21b46b&v=4
url: https://github.com/dcooper01
- login: d3vzer0
avatarUrl: https://avatars3.githubusercontent.com/u/34250156?u=c50c9df0e34f411f7e5f050a72e8d89696284eba&v=4
url: https://github.com/d3vzer0
- login: AjitZK
avatarUrl: https://avatars0.githubusercontent.com/u/40203625?u=70c479337ab95d76ab59ae17ba0a988f1b43c0c6&v=4
url: https://github.com/AjitZK
- login: dbanty
avatarUrl: https://avatars2.githubusercontent.com/u/43723790?u=0cf33e4f40efc2ea206a1189fd63a11344eb88ed&v=4
url: https://github.com/dbanty
- login: Brontomerus
avatarUrl: https://avatars0.githubusercontent.com/u/61284158?u=c00d807195815014d0b6597b3801ee9c494802dd&v=4
url: https://github.com/Brontomerus
- login: primer-api
avatarUrl: https://avatars2.githubusercontent.com/u/62152773?u=4549d79b0ad1d30ecfbef6c6933593e90e819c75&v=4
url: https://github.com/primer-api
- login: tkrestiankova
avatarUrl: https://avatars2.githubusercontent.com/u/67013045?u=6f06d28dba7e46aa363af2840d7b028e4d7bcbd9&v=4
url: https://github.com/tkrestiankova
- login: daverin
avatarUrl: https://avatars1.githubusercontent.com/u/70378377?u=6d1814195c0de7162820eaad95a25b423a3869c0&v=4
url: https://github.com/daverin

11
docs/en/data/sponsors.yml Normal file
View File

@@ -0,0 +1,11 @@
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://testdriven.io/courses/tdd-fastapi/
title: Learn to build high-quality web apps with best practices
img: https://fastapi.tiangolo.com/img/sponsors/testdriven.svg
- url: https://jobs.bywetransfer.com/
title: WeTransfer - We deal in big ideas. You in?
img: https://fastapi.tiangolo.com/img/sponsors/wetransfer.svg

View File

@@ -23,7 +23,7 @@ Each of those response `dict`s can have a key `model`, containing a Pydantic mod
For example, to declare another response with a status code `404` and a Pydantic model `Message`, you can write:
```Python hl_lines="18 23"
```Python hl_lines="18 23"
{!../../../docs_src/additional_responses/tutorial001.py!}
```
@@ -44,7 +44,7 @@ For example, to declare another response with a status code `404` and a Pydantic
The generated responses in the OpenAPI for this *path operation* will be:
```JSON hl_lines="3 4 5 6 7 8 9 10 11 12"
```JSON hl_lines="3-12"
{
"responses": {
"404": {
@@ -83,7 +83,7 @@ The generated responses in the OpenAPI for this *path operation* will be:
The schemas are referenced to another place inside the OpenAPI schema:
```JSON hl_lines="4 5 6 7 8 9 10 11 12 13 14 15 16"
```JSON hl_lines="4-16"
{
"components": {
"schemas": {
@@ -168,7 +168,7 @@ You can use this same `responses` parameter to add different media types for the
For example, you can add an additional media type of `image/png`, declaring that your *path operation* can return a JSON object (with media type `application/json`) or a PNG image:
```Python hl_lines="19 20 21 22 23 24 28"
```Python hl_lines="19-24 28"
{!../../../docs_src/additional_responses/tutorial002.py!}
```
@@ -192,7 +192,7 @@ For example, you can declare a response with a status code `404` that uses a Pyd
And a response with a status code `200` that uses your `response_model`, but includes a custom `example`:
```Python hl_lines="20 21 22 23 24 25 26 27 28 29 30 31"
```Python hl_lines="20-31"
{!../../../docs_src/additional_responses/tutorial003.py!}
```
@@ -228,7 +228,7 @@ You can use that technique to re-use some predefined responses in your *path ope
For example:
```Python hl_lines="13 14 15 16 17 26"
```Python hl_lines="13-17 26"
{!../../../docs_src/additional_responses/tutorial004.py!}
```

View File

@@ -23,7 +23,7 @@ Later, for your production application, you might want to use a database server
* Create a `metadata` object.
* Create a table `notes` using the `metadata` object.
```Python hl_lines="4 14 16 17 18 19 20 21 22"
```Python hl_lines="4 14 16-22"
{!../../../docs_src/async_sql_databases/tutorial001.py!}
```
@@ -38,7 +38,7 @@ Later, for your production application, you might want to use a database server
* Create a `DATABASE_URL`.
* Create a `database` object.
```Python hl_lines="3 9 12"
```Python hl_lines="3 9 12"
{!../../../docs_src/async_sql_databases/tutorial001.py!}
```
@@ -54,7 +54,7 @@ Here, this section would run directly, right before starting your **FastAPI** ap
* Create an `engine`.
* Create all the tables from the `metadata` object.
```Python hl_lines="25 26 27 28"
```Python hl_lines="25-28"
{!../../../docs_src/async_sql_databases/tutorial001.py!}
```
@@ -65,7 +65,7 @@ Create Pydantic models for:
* Notes to be created (`NoteIn`).
* Notes to be returned (`Note`).
```Python hl_lines="31 32 33 36 37 38 39"
```Python hl_lines="31-33 36-39"
{!../../../docs_src/async_sql_databases/tutorial001.py!}
```
@@ -78,7 +78,7 @@ So, you will be able to see it all in the interactive API docs.
* Create your `FastAPI` application.
* Create event handlers to connect and disconnect from the database.
```Python hl_lines="42 45 46 47 50 51 52"
```Python hl_lines="42 45-47 50-52"
{!../../../docs_src/async_sql_databases/tutorial001.py!}
```
@@ -86,7 +86,7 @@ So, you will be able to see it all in the interactive API docs.
Create the *path operation function* to read notes:
```Python hl_lines="55 56 57 58"
```Python hl_lines="55-58"
{!../../../docs_src/async_sql_databases/tutorial001.py!}
```
@@ -103,7 +103,7 @@ That documents (and validates, serializes, filters) the output data, as a `list`
Create the *path operation function* to create notes:
```Python hl_lines="61 62 63 64 65"
```Python hl_lines="61-65"
{!../../../docs_src/async_sql_databases/tutorial001.py!}
```

View File

@@ -77,7 +77,7 @@ The marker `@pytest.mark.asyncio` tells pytest that this test function should be
Then we can create an `AsyncClient` with the app, and send async requests to it, using `await`.
```Python hl_lines="9 10"
```Python hl_lines="9-10"
{!../../../docs_src/async_tests/test_main.py!}
```

View File

@@ -44,7 +44,7 @@ proxy --> server
The docs UI would also need the OpenAPI schema to declare that this API `server` is located at `/api/v1` (behind the proxy). For example:
```JSON hl_lines="4 5 6 7 8"
```JSON hl_lines="4-8"
{
"openapi": "3.0.2",
// More stuff here
@@ -290,13 +290,13 @@ If you pass a custom list of `servers` and there's a `root_path` (because your A
For example:
```Python hl_lines="4 5 6 7"
```Python hl_lines="4-7"
{!../../../docs_src/behind_a_proxy/tutorial003.py!}
```
Will generate an OpenAPI schema like:
```JSON hl_lines="5 6 7"
```JSON hl_lines="5-7"
{
"openapi": "3.0.2",
// More stuff here

View File

@@ -36,7 +36,7 @@ If there's no `gzip` in the header, it will not try to decompress the body.
That way, the same route class can handle gzip compressed or uncompressed requests.
```Python hl_lines="8 9 10 11 12 13 14 15"
```Python hl_lines="8-15"
{!../../../docs_src/custom_request_and_route/tutorial001.py!}
```
@@ -50,7 +50,7 @@ This method returns a function. And that function is what will receive a request
Here we use it to create a `GzipRequest` from the original request.
```Python hl_lines="18 19 20 21 22 23 24 25 26"
```Python hl_lines="18-26"
{!../../../docs_src/custom_request_and_route/tutorial001.py!}
```
@@ -84,13 +84,13 @@ We can also use this same approach to access the request body in an exception ha
All we need to do is handle the request inside a `try`/`except` block:
```Python hl_lines="13 15"
```Python hl_lines="13 15"
{!../../../docs_src/custom_request_and_route/tutorial002.py!}
```
If an exception occurs, the`Request` instance will still be in scope, so we can read and make use of the request body when handling the error:
```Python hl_lines="16 17 18"
```Python hl_lines="16-18"
{!../../../docs_src/custom_request_and_route/tutorial002.py!}
```
@@ -104,6 +104,6 @@ You can also set the `route_class` parameter of an `APIRouter`:
In this example, the *path operations* under the `router` will use the custom `TimedRoute` class, and will have an extra `X-Response-Time` header in the response with the time it took to generate the response:
```Python hl_lines="13 14 15 16 17 18 19 20"
```Python hl_lines="13-20"
{!../../../docs_src/custom_request_and_route/tutorial003.py!}
```

View File

@@ -21,7 +21,7 @@ For example, if you are squeezing performance, you can install and use <a href="
Import the `Response` class (sub-class) you want to use and declare it in the *path operation decorator*.
```Python hl_lines="2 7"
```Python hl_lines="2 7"
{!../../../docs_src/custom_response/tutorial001b.py!}
```
@@ -40,9 +40,9 @@ Import the `Response` class (sub-class) you want to use and declare it in the *p
To return a response with HTML directly from **FastAPI**, use `HTMLResponse`.
* Import `HTMLResponse`.
* Pass `HTMLResponse` as the parameter `content_type` of your *path operation*.
* Pass `HTMLResponse` as the parameter `response_class` of your *path operation decorator*.
```Python hl_lines="2 7"
```Python hl_lines="2 7"
{!../../../docs_src/custom_response/tutorial002.py!}
```
@@ -59,7 +59,7 @@ As seen in [Return a Response directly](response-directly.md){.internal-link tar
The same example from above, returning an `HTMLResponse`, could look like:
```Python hl_lines="2 7 19"
```Python hl_lines="2 7 19"
{!../../../docs_src/custom_response/tutorial003.py!}
```
@@ -79,7 +79,7 @@ The `response_class` will then be used only to document the OpenAPI *path operat
For example, it could be something like:
```Python hl_lines="7 23 21"
```Python hl_lines="7 21 23"
{!../../../docs_src/custom_response/tutorial004.py!}
```
@@ -150,7 +150,7 @@ An alternative JSON response using <a href="https://github.com/ultrajson/ultrajs
!!! warning
`ujson` is less careful than Python's built-in implementation in how it handles some edge-cases.
```Python hl_lines="2 7"
```Python hl_lines="2 7"
{!../../../docs_src/custom_response/tutorial001.py!}
```
@@ -179,7 +179,7 @@ If you have a file-like object (e.g. the object returned by `open()`), you can r
This includes many libraries to interact with cloud storage, video processing, and others.
```Python hl_lines="2 10 11"
```Python hl_lines="2 10-11"
{!../../../docs_src/custom_response/tutorial008.py!}
```
@@ -211,7 +211,7 @@ The parameter that defines this is `default_response_class`.
In the example below, **FastAPI** will use `ORJSONResponse` by default, in all *path operations*, instead of `JSONResponse`.
```Python hl_lines="2 4"
```Python hl_lines="2 4"
{!../../../docs_src/custom_response/tutorial010.py!}
```

View File

@@ -43,7 +43,7 @@ For example, let's add <a href="https://github.com/Rebilly/ReDoc/blob/master/doc
First, write all your **FastAPI** application as normally:
```Python hl_lines="1 4 7 8 9"
```Python hl_lines="1 4 7-9"
{!../../../docs_src/extending_openapi/tutorial001.py!}
```
@@ -51,7 +51,7 @@ First, write all your **FastAPI** application as normally:
Then, use the same utility function to generate the OpenAPI schema, inside a `custom_openapi()` function:
```Python hl_lines="2 15 16 17 18 19 20"
```Python hl_lines="2 15-20"
{!../../../docs_src/extending_openapi/tutorial001.py!}
```
@@ -59,7 +59,7 @@ Then, use the same utility function to generate the OpenAPI schema, inside a `cu
Now you can add the ReDoc extension, adding a custom `x-logo` to the `info` "object" in the OpenAPI schema:
```Python hl_lines="21 22 23"
```Python hl_lines="21-23"
{!../../../docs_src/extending_openapi/tutorial001.py!}
```
@@ -71,7 +71,7 @@ That way, your application won't have to generate the schema every time a user o
It will be generated only once, and then the same cached schema will be used for the next requests.
```Python hl_lines="13 14 24 25"
```Python hl_lines="13-14 24-25"
{!../../../docs_src/extending_openapi/tutorial001.py!}
```
@@ -172,7 +172,7 @@ $ pip install aiofiles
* Import `StaticFiles`.
* "Mount" a `StaticFiles()` instance in a specific path.
```Python hl_lines="7 11"
```Python hl_lines="7 11"
{!../../../docs_src/extending_openapi/tutorial002.py!}
```
@@ -224,7 +224,7 @@ You can re-use FastAPI's internal functions to create the HTML pages for the doc
And similarly for ReDoc...
```Python hl_lines="2 3 4 5 6 14 15 16 17 18 19 20 21 22 25 26 27 30 31 32 33 34 35 36"
```Python hl_lines="2-6 14-22 25-27 30-36"
{!../../../docs_src/extending_openapi/tutorial002.py!}
```
@@ -239,7 +239,7 @@ And similarly for ReDoc...
Now, to be able to test that everything works, create a *path operation*:
```Python hl_lines="39 40 41"
```Python hl_lines="39-41"
{!../../../docs_src/extending_openapi/tutorial002.py!}
```

View File

@@ -10,7 +10,7 @@ GraphQL is implemented with Graphene, you can check <a href="https://docs.graphe
Import `graphene` and define your GraphQL data:
```Python hl_lines="1 6 7 8 9 10"
```Python hl_lines="1 6-10"
{!../../../docs_src/graphql/tutorial001.py!}
```
@@ -18,7 +18,7 @@ Import `graphene` and define your GraphQL data:
Then import and add Starlette's `GraphQLApp`:
```Python hl_lines="3 14"
```Python hl_lines="3 14"
{!../../../docs_src/graphql/tutorial001.py!}
```

View File

@@ -16,3 +16,9 @@ In the next sections you will see other options, configurations, and additional
You could still use most of the features in **FastAPI** with the knowledge from the main [Tutorial - User Guide](../tutorial/){.internal-link target=_blank}.
And the next sections assume you already read it, and assume that you know those main ideas.
## TestDriven.io course
If you would like to take an advanced-beginner course to complement this section of the docs, you might want to check: <a href="https://testdriven.io/courses/tdd-fastapi/" class="external-link" target="_blank">Test-Driven Development with FastAPI and Docker</a> by **TestDriven.io**.
They are currently donating 10% of all profits to the development of **FastAPI**. 🎉 😄

View File

@@ -62,7 +62,7 @@ Any incoming requests to `http` or `ws` will be redirected to the secure scheme
Enforces that all incoming requests have a correctly set `Host` header, in order to guard against HTTP Host Header attacks.
```Python hl_lines="2 6 7 8"
```Python hl_lines="2 6-8"
{!../../../docs_src/advanced_middleware/tutorial002.py!}
```

View File

@@ -19,7 +19,7 @@ You can adapt it to any other NoSQL database like:
For now, don't pay attention to the rest, only the imports:
```Python hl_lines="3 4 5"
```Python hl_lines="3-5"
{!../../../docs_src/nosql_databases/tutorial001.py!}
```
@@ -54,7 +54,7 @@ This utility function will:
* Set defaults for timeouts.
* Return it.
```Python hl_lines="12 13 14 15 16 17 18 19 20 21"
```Python hl_lines="12-21"
{!../../../docs_src/nosql_databases/tutorial001.py!}
```
@@ -66,7 +66,7 @@ As **Couchbase** "documents" are actually just "JSON objects", we can model them
First, let's create a `User` model:
```Python hl_lines="24 25 26 27 28"
```Python hl_lines="24-28"
{!../../../docs_src/nosql_databases/tutorial001.py!}
```
@@ -80,7 +80,7 @@ This will have the data that is actually stored in the database.
We don't create it as a subclass of Pydantic's `BaseModel` but as a subclass of our own `User`, because it will have all the attributes in `User` plus a couple more:
```Python hl_lines="31 32 33"
```Python hl_lines="31-33"
{!../../../docs_src/nosql_databases/tutorial001.py!}
```
@@ -100,7 +100,7 @@ Now create a function that will:
By creating a function that is only dedicated to getting your user from a `username` (or any other parameter) independent of your *path operation function*, you can more easily re-use it in multiple parts and also add <abbr title="Automated test, written in code, that checks if another piece of code is working correctly.">unit tests</abbr> for it:
```Python hl_lines="36 37 38 39 40 41 42"
```Python hl_lines="36-42"
{!../../../docs_src/nosql_databases/tutorial001.py!}
```
@@ -143,9 +143,9 @@ UserInDB(username="johndoe", hashed_password="some_hash")
As our code is calling Couchbase and we are not using the <a href="https://docs.couchbase.com/python-sdk/2.5/async-programming.html#asyncio-python-3-5" class="external-link" target="_blank">experimental Python <code>await</code> support</a>, we should declare our function with normal `def` instead of `async def`.
Also, Couchbase recommends not using a single `Bucket` object in multiple "<abbr title="A sequence of code being executed by the program, while at the same time, or at intervals, there can be others being executed too.">thread</abbr>s", so, we can get just get the bucket directly and pass it to our utility functions:
Also, Couchbase recommends not using a single `Bucket` object in multiple "<abbr title="A sequence of code being executed by the program, while at the same time, or at intervals, there can be others being executed too.">thread</abbr>s", so, we can just get the bucket directly and pass it to our utility functions:
```Python hl_lines="49 50 51 52 53"
```Python hl_lines="49-53"
{!../../../docs_src/nosql_databases/tutorial001.py!}
```

View File

@@ -31,7 +31,7 @@ It will have a *path operation* that will receive an `Invoice` body, and a query
This part is pretty normal, most of the code is probably already familiar to you:
```Python hl_lines="10 11 12 13 14 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54"
```Python hl_lines="10-14 37-54"
{!../../../docs_src/openapi_callbacks/tutorial001.py!}
```
@@ -83,16 +83,7 @@ So we are going to use that same knowledge to document how the *external API* sh
First create a new `APIRouter` that will contain one or more callbacks.
This router will never be added to an actual `FastAPI` app (i.e. it will never be passed to `app.include_router(...)`).
Because of that, you need to declare what will be the `default_response_class`, and set it to `JSONResponse`.
!!! Note "Technical Details"
The `response_class` is normally set by the `FastAPI` app during the call to `app.include_router(some_router)`.
But as we are never calling `app.include_router(some_router)`, we need to set the `default_response_class` during creation of the `APIRouter`.
```Python hl_lines="5 26"
```Python hl_lines="5 26"
{!../../../docs_src/openapi_callbacks/tutorial001.py!}
```
@@ -105,7 +96,7 @@ It should look just like a normal FastAPI *path operation*:
* It should probably have a declaration of the body it should receive, e.g. `body: InvoiceEvent`.
* And it could also have a declaration of the response it should return, e.g. `response_model=InvoiceEventReceived`.
```Python hl_lines="17 18 19 22 23 29 30 31 32 33"
```Python hl_lines="17-19 22-23 29-33"
{!../../../docs_src/openapi_callbacks/tutorial001.py!}
```

View File

@@ -19,7 +19,7 @@ If you want to use your APIs' function names as `operationId`s, you can iterate
You should do it after adding all your *path operations*.
```Python hl_lines="2 12 13 14 15 16 17 18 19 20 21 24"
```Python hl_lines="2 12-21 24"
{!../../../docs_src/path_operation_advanced_configuration/tutorial002.py!}
```
@@ -47,6 +47,6 @@ Adding an `\f` (an escaped "form feed" character) causes **FastAPI** to truncate
It won't show up in the documentation, but other tools (such as Sphinx) will be able to use the rest.
```Python hl_lines="19 20 21 22 23 24 25 26 27 28 29"
```Python hl_lines="19-29"
{!../../../docs_src/path_operation_advanced_configuration/tutorial004.py!}
```

View File

@@ -6,7 +6,7 @@ You can declare a parameter of type `Response` in your *path operation function*
And then you can set cookies in that *temporal* response object.
```Python hl_lines="1 8 9"
```Python hl_lines="1 8-9"
{!../../../docs_src/response_cookies/tutorial002.py!}
```
@@ -26,7 +26,7 @@ To do that, you can create a response as described in [Return a Response Directl
Then set Cookies in it, and then return it:
```Python hl_lines="10 11 12"
```Python hl_lines="10-12"
{!../../../docs_src/response_cookies/tutorial001.py!}
```

View File

@@ -31,7 +31,7 @@ For example, you cannot put a Pydantic model in a `JSONResponse` without first c
For those cases, you can use the `jsonable_encoder` to convert your data before passing it to a response:
```Python hl_lines="6 7 21 22"
```Python hl_lines="6-7 21-22"
{!../../../docs_src/response_directly/tutorial001.py!}
```

View File

@@ -6,7 +6,7 @@ You can declare a parameter of type `Response` in your *path operation function*
And then you can set headers in that *temporal* response object.
```Python hl_lines="1 7 8"
```Python hl_lines="1 7-8"
{!../../../docs_src/response_headers/tutorial002.py!}
```
@@ -24,7 +24,7 @@ You can also add headers when you return a `Response` directly.
Create a response as described in [Return a Response Directly](response-directly.md){.internal-link target=_blank} and pass the headers as an additional parameter:
```Python hl_lines="10 11 12"
```Python hl_lines="10-12"
{!../../../docs_src/response_headers/tutorial001.py!}
```

View File

@@ -20,7 +20,7 @@ Then, when you type that username and password, the browser sends them in the he
* It returns an object of type `HTTPBasicCredentials`:
* It contains the `username` and `password` sent.
```Python hl_lines="2 6 10"
```Python hl_lines="2 6 10"
{!../../../docs_src/security/tutorial006.py!}
```
@@ -36,7 +36,7 @@ Use a dependency to check if the username and password are correct.
For this, use the Python standard module <a href="https://docs.python.org/3/library/secrets.html" class="external-link" target="_blank">`secrets`</a> to check the username and password:
```Python hl_lines="1 11 12 13"
```Python hl_lines="1 11-13"
{!../../../docs_src/security/tutorial007.py!}
```
@@ -54,9 +54,9 @@ But by using the `secrets.compare_digest()` it will be secure against a type of
But what's a "timing attack"?
Let's imagine an attacker is trying to guess the username and password.
Let's imagine some attackers are trying to guess the username and password.
And that attacker sends a request with a username `johndoe` and a password `love123`.
And they send a request with a username `johndoe` and a password `love123`.
Then the Python code in your application would be equivalent to something like:
@@ -67,7 +67,7 @@ if "johndoe" == "stanleyjobson" and "love123" == "swordfish":
But right at the moment Python compares the first `j` in `johndoe` to the first `s` in `stanleyjobson`, it will return `False`, because it already knows that those two strings are not the same, thinking that "there's no need to waste more computation comparing the rest of the letters". And your application will say "incorrect user or password".
But then the attacker tries with username `stanleyjobsox` and password `love123`.
But then the attackers try with username `stanleyjobsox` and password `love123`.
And your application code does something like:
@@ -78,17 +78,17 @@ if "stanleyjobsox" == "stanleyjobson" and "love123" == "swordfish":
Python will have to compare the whole `stanleyjobso` in both `stanleyjobsox` and `stanleyjobson` before realizing that both strings are not the same. So it will take some extra microseconds to reply back "incorrect user or password".
#### The time to answer helps the attacker
#### The time to answer helps the attackers
At that point, by noticing that the server took some microseconds longer to send the "incorrect user or password" response, the attacker will know that she/he got _something_ right, some of the initial letters were right.
At that point, by noticing that the server took some microseconds longer to send the "incorrect user or password" response, the attackers will know that they got _something_ right, some of the initial letters were right.
And then she/he can try again knowing that it's probably something more similar to `stanleyjobsox` than to `johndoe`.
And then they can try again knowing that it's probably something more similar to `stanleyjobsox` than to `johndoe`.
#### A "professional" attack
Of course, the attacker would not try all this by hand, she/he would write a program to do it, possibly with thousands or millions of tests per second. And would get just one extra correct letter at a time.
Of course, the attackers would not try all this by hand, they would write a program to do it, possibly with thousands or millions of tests per second. And would get just one extra correct letter at a time.
But doing that, in some minutes or hours the attacker would have guessed the correct username and password, with the "help" of our application, just using the time taken to answer.
But doing that, in some minutes or hours the attackers would have guessed the correct username and password, with the "help" of our application, just using the time taken to answer.
#### Fix it with `secrets.compare_digest()`
@@ -102,6 +102,6 @@ That way, using `secrets.compare_digest()` in your application code, it will be
After detecting that the credentials are incorrect, return an `HTTPException` with a status code 401 (the same returned when no credentials are provided) and add the header `WWW-Authenticate` to make the browser show the login prompt again:
```Python hl_lines="15 16 17 18 19"
```Python hl_lines="15-19"
{!../../../docs_src/security/tutorial007.py!}
```

View File

@@ -56,7 +56,7 @@ They are normally used to declare specific security permissions, for example:
First, let's quickly see the parts that change from the examples in the main **Tutorial - User Guide** for [OAuth2 with Password (and hashing), Bearer with JWT tokens](../../tutorial/security/oauth2-jwt.md){.internal-link target=_blank}. Now using OAuth2 scopes:
```Python hl_lines="2 4 8 12 46 64 105 107 108 109 110 111 112 113 114 115 121 122 123 124 128 129 130 131 132 133 134 139 153"
```Python hl_lines="2 4 8 12 46 64 105 107-115 121-124 128-134 139 153"
{!../../../docs_src/security/tutorial005.py!}
```
@@ -68,7 +68,7 @@ The first change is that now we are declaring the OAuth2 security scheme with tw
The `scopes` parameter receives a `dict` with each scope as a key and the description as the value:
```Python hl_lines="62 63 64 65"
```Python hl_lines="62-65"
{!../../../docs_src/security/tutorial005.py!}
```
@@ -159,7 +159,7 @@ We create an `HTTPException` that we can re-use (`raise`) later at several point
In this exception, we include the scopes required (if any) as a string separated by spaces (using `scope_str`). We put that string containing the scopes in in the `WWW-Authenticate` header (this is part of the spec).
```Python hl_lines="105 107 108 109 110 111 112 113 114 115"
```Python hl_lines="105 107-115"
{!../../../docs_src/security/tutorial005.py!}
```
@@ -177,7 +177,7 @@ Instead of, for example, a `dict`, or something else, as it could break the appl
We also verify that we have a user with that username, and if not, we raise that same exception we created before.
```Python hl_lines="46 116 117 118 119 120 121 122 123 124 125 126 127"
```Python hl_lines="46 116-127"
{!../../../docs_src/security/tutorial005.py!}
```
@@ -187,7 +187,7 @@ We now verify that all the scopes required, by this dependency and all the depen
For this, we use `security_scopes.scopes`, that contains a `list` with all these scopes as `str`.
```Python hl_lines="128 129 130 131 132 133 134"
```Python hl_lines="128-134"
{!../../../docs_src/security/tutorial005.py!}
```

View File

@@ -135,7 +135,7 @@ The same way as with Pydantic models, you declare class attributes with type ann
You can use all the same validation features and tools you use for Pydantic models, like different data types and additional validations with `Field()`.
```Python hl_lines="2 5 6 7 8 11"
```Python hl_lines="2 5-8 11"
{!../../../docs_src/settings/tutorial001.py!}
```
@@ -150,7 +150,7 @@ Next it will convert and validate the data. So, when you use that `settings` obj
Then you can use the new `settings` object in your application:
```Python hl_lines="18 19 20"
```Python hl_lines="18-20"
{!../../../docs_src/settings/tutorial001.py!}
```
@@ -189,7 +189,7 @@ For example, you could have a file `config.py` with:
And then use it in a file `main.py`:
```Python hl_lines="3 11 12 13"
```Python hl_lines="3 11-13"
{!../../../docs_src/settings/app01/main.py!}
```
@@ -216,7 +216,7 @@ Notice that now we don't create a default instance `settings = Settings()`.
Now we create a dependency that returns a new `config.Settings()`.
```Python hl_lines="5 11 12"
```Python hl_lines="5 11-12"
{!../../../docs_src/settings/app02/main.py!}
```
@@ -227,7 +227,7 @@ Now we create a dependency that returns a new `config.Settings()`.
And then we can require it from the *path operation function* as a dependency and use it anywhere we need it.
```Python hl_lines="16 18 19 20"
```Python hl_lines="16 18-20"
{!../../../docs_src/settings/app02/main.py!}
```
@@ -235,7 +235,7 @@ And then we can require it from the *path operation function* as a dependency an
Then it would be very easy to provide a different settings object during testing by creating a dependency override for `get_settings`:
```Python hl_lines="8 9 12 21"
```Python hl_lines="8-9 12 21"
{!../../../docs_src/settings/app02/test_main.py!}
```
@@ -272,7 +272,7 @@ APP_NAME="ChimichangApp"
And then update your `config.py` with:
```Python hl_lines="9 10"
```Python hl_lines="9-10"
{!../../../docs_src/settings/app03/config.py!}
```

View File

@@ -7,7 +7,7 @@
If you are starting a project from scratch, you are probably better off with SQLAlchemy ORM ([SQL (Relational) Databases](../tutorial/sql-databases.md){.internal-link target=_blank}), or any other async ORM.
If you already have a code base that uses <a href="http://docs.peewee-orm.com/en/latest/" class="external-link" target="_blank">Peewee ORM</a>, you can check here how to use it with **FastAPI**.
If you already have a code base that uses <a href="https://docs.peewee-orm.com/en/latest/" class="external-link" target="_blank">Peewee ORM</a>, you can check here how to use it with **FastAPI**.
!!! warning "Python 3.7+ required"
You will need Python 3.7 or above to safely use Peewee with FastAPI.
@@ -25,7 +25,7 @@ But if you need to change some of the defaults, support more than one predefined
Nevertheless, it's possible to do it, and here you'll see exactly what code you have to add to be able to use Peewee with FastAPI.
!!! note "Technical Details"
You can read more about Peewee's stand about async in Python <a href="http://docs.peewee-orm.com/en/latest/peewee/database.html#async-with-gevent" class="external-link" target="_blank">in the docs</a>, <a href="https://github.com/coleifer/peewee/issues/263#issuecomment-517347032" class="external-link" target="_blank">an issue</a>, <a href="https://github.com/coleifer/peewee/pull/2072#issuecomment-563215132" class="external-link" target="_blank">a PR</a>.
You can read more about Peewee's stand about async in Python <a href="https://docs.peewee-orm.com/en/latest/peewee/database.html#async-with-gevent" class="external-link" target="_blank">in the docs</a>, <a href="https://github.com/coleifer/peewee/issues/263#issuecomment-517347032" class="external-link" target="_blank">an issue</a>, <a href="https://github.com/coleifer/peewee/pull/2072#issuecomment-563215132" class="external-link" target="_blank">a PR</a>.
## The same app
@@ -113,7 +113,7 @@ This might seem a bit complex (and it actually is), you don't really need to com
We will create a `PeeweeConnectionState`:
```Python hl_lines="10 11 12 13 14 15 16 17 18 19"
```Python hl_lines="10-19"
{!../../../docs_src/sql_databases_peewee/sql_app/database.py!}
```
@@ -161,7 +161,7 @@ This is the same you would do if you followed the Peewee tutorial and updated th
Import `db` from `database` (the file `database.py` from above) and use it here.
```Python hl_lines="3 6 7 8 9 10 11 12 15 16 17 18 19 20 21"
```Python hl_lines="3 6-12 15-21"
{!../../../docs_src/sql_databases_peewee/sql_app/models.py!}
```
@@ -189,7 +189,7 @@ Now let's check the file `sql_app/schemas.py`.
Create all the same Pydantic models as in the SQLAlchemy tutorial:
```Python hl_lines="16 17 18 21 22 25 26 27 28 29 30 34 35 38 39 42 43 44 45 46 47 48"
```Python hl_lines="16-18 21-22 25-30 34-35 38-39 42-48"
{!../../../docs_src/sql_databases_peewee/sql_app/schemas.py!}
```
@@ -214,7 +214,7 @@ But recent versions of Pydantic allow providing a custom class that inherits fro
We are going to create a custom `PeeweeGetterDict` class and use it in all the same Pydantic *models* / schemas that use `orm_mode`:
```Python hl_lines="3 8 9 10 11 12 13 31 49"
```Python hl_lines="3 8-13 31 49"
{!../../../docs_src/sql_databases_peewee/sql_app/schemas.py!}
```
@@ -235,7 +235,7 @@ Now let's see the file `sql_app/crud.py`.
Create all the same CRUD utils as in the SQLAlchemy tutorial, all the code is very similar:
```Python hl_lines="1 4 5 8 9 12 13 16 17 18 19 20 23 24 27 28 29 30"
```Python hl_lines="1 4-5 8-9 12-13 16-20 23-24 27-30"
{!../../../docs_src/sql_databases_peewee/sql_app/crud.py!}
```
@@ -259,7 +259,7 @@ And now in the file `sql_app/main.py` let's integrate and use all the other part
In a very simplistic way create the database tables:
```Python hl_lines="9 10 11"
```Python hl_lines="9-11"
{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
```
@@ -267,7 +267,7 @@ In a very simplistic way create the database tables:
Create a dependency that will connect the database right at the beginning of a request and disconnect it at the end:
```Python hl_lines="23 24 25 26 27 28 29"
```Python hl_lines="23-29"
{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
```
@@ -291,7 +291,7 @@ For all the `contextvars` parts to work, we need to make sure we have an indepen
For that, we need to create another `async` dependency `reset_db_state()` that is used as a sub-dependency in `get_db()`. It will set the value for the context variable (with just a default `dict`) that will be used as the database state for the whole request. And then the dependency `get_db()` will store in it the database state (connection, transactions, etc).
```Python hl_lines="18 19 20"
```Python hl_lines="18-20"
{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
```
@@ -306,11 +306,11 @@ For the **next request**, as we will reset that context variable again in the `a
#### Peewee Proxy
If you are using a <a href="http://docs.peewee-orm.com/en/latest/peewee/database.html#dynamically-defining-a-database" class="external-link" target="_blank">Peewee Proxy</a>, the actual database is at `db.obj`.
If you are using a <a href="https://docs.peewee-orm.com/en/latest/peewee/database.html#dynamically-defining-a-database" class="external-link" target="_blank">Peewee Proxy</a>, the actual database is at `db.obj`.
So, you would reset it with:
```Python hl_lines="3 4"
```Python hl_lines="3-4"
async def reset_db_state():
database.db.obj._state._state.set(db_state_default.copy())
database.db.obj._state.reset()
@@ -320,7 +320,7 @@ async def reset_db_state():
Now, finally, here's the standard **FastAPI** *path operations* code.
```Python hl_lines="32 33 34 35 36 37 40 41 42 43 46 47 48 49 50 51 52 53 56 57 58 59 60 61 62 65 66 67 68 71 72 73 74 75 76 77 78 79"
```Python hl_lines="32-37 40-43 46-53 56-62 65-68 71-79"
{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
```

View File

@@ -10,7 +10,7 @@ If you need to have two independent FastAPI applications, with their own indepen
First, create the main, top-level, **FastAPI** application, and its *path operations*:
```Python hl_lines="3 6 7 8"
```Python hl_lines="3 6-8"
{!../../../docs_src/sub_applications/tutorial001.py!}
```
@@ -20,7 +20,7 @@ Then, create your sub-application, and its *path operations*.
This sub-application is just another standard FastAPI application, but this is the one that will be "mounted":
```Python hl_lines="11 14 15 16"
```Python hl_lines="11 14-16"
{!../../../docs_src/sub_applications/tutorial001.py!}
```
@@ -30,7 +30,7 @@ In your top-level application, `app`, mount the sub-application, `subapi`.
In this case, it will be mounted at the path `/subapi`:
```Python hl_lines="11 19"
```Python hl_lines="11 19"
{!../../../docs_src/sub_applications/tutorial001.py!}
```

View File

@@ -39,7 +39,7 @@ $ pip install aiofiles
* Declare a `Request` parameter in the *path operation* that will return a template.
* Use the `templates` you created to render and return a `TemplateResponse`, passing the `request` as one of the key-value pairs in the Jinja2 "context".
```Python hl_lines="4 11 15 16"
```Python hl_lines="4 11 15-16"
{!../../../docs_src/templates/tutorial001.py!}
```

View File

@@ -26,7 +26,7 @@ We create a new file at `sql_app/tests/test_sql_app.py`.
So the new file structure looks like:
``` hl_lines="9 10 11"
``` hl_lines="9-11"
.
└── sql_app
├── __init__.py
@@ -48,7 +48,7 @@ For the tests we'll use a file `test.db` instead of `sql_app.db`.
But the rest of the session code is more or less the same, we just copy it.
```Python hl_lines="8 9 10 11 12 13"
```Python hl_lines="8-13"
{!../../../docs_src/sql_databases/sql_app/tests/test_sql_app.py!}
```
@@ -77,7 +77,7 @@ So we add that line here, with the new file.
Now we create the dependency override and add it to the overrides for our app.
```Python hl_lines="19 20 21 22 23 24 27"
```Python hl_lines="19-24 27"
{!../../../docs_src/sql_databases/sql_app/tests/test_sql_app.py!}
```
@@ -88,7 +88,7 @@ Now we create the dependency override and add it to the overrides for our app.
Then we can just test the app as normally.
```Python hl_lines="32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47"
```Python hl_lines="32-47"
{!../../../docs_src/sql_databases/sql_app/tests/test_sql_app.py!}
```

View File

@@ -28,7 +28,7 @@ To override a dependency for testing, you put as a key the original dependency (
And then **FastAPI** will call that override instead of the original dependency.
```Python hl_lines="26 27 30"
```Python hl_lines="26-27 30"
{!../../../docs_src/dependency_testing/tutorial001.py!}
```

View File

@@ -2,6 +2,6 @@
When you need your event handlers (`startup` and `shutdown`) to run in your tests, you can use the `TestClient` with a `with` statement:
```Python hl_lines="9 10 11 12 20 21 22 23 24"
```Python hl_lines="9-12 20-24"
{!../../../docs_src/app_testing/tutorial003.py!}
```

View File

@@ -4,7 +4,7 @@ You can use the same `TestClient` to test WebSockets.
For this, you use the `TestClient` in a `with` statement, connecting to the WebSocket:
```Python hl_lines="27 28 29 30 31"
```Python hl_lines="27-31"
{!../../../docs_src/app_testing/tutorial002.py!}
```

View File

@@ -29,7 +29,7 @@ Let's imagine you want to get the client's IP address/host inside of your *path
For that you need to access the request directly.
```Python hl_lines="1 7 8"
```Python hl_lines="1 7-8"
{!../../../docs_src/using_request_directly/tutorial001.py!}
```

View File

@@ -24,7 +24,7 @@ In production you would have one of the options above.
But it's the simplest way to focus on the server-side of WebSockets and have a working example:
```Python hl_lines="2 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 41 42 43"
```Python hl_lines="2 6-38 41-43"
{!../../../docs_src/websockets/tutorial001.py!}
```
@@ -32,7 +32,7 @@ But it's the simplest way to focus on the server-side of WebSockets and have a w
In your **FastAPI** application, create a `websocket`:
```Python hl_lines="1 46 47"
```Python hl_lines="1 46-47"
{!../../../docs_src/websockets/tutorial001.py!}
```
@@ -45,7 +45,7 @@ In your **FastAPI** application, create a `websocket`:
In your WebSocket route you can `await` for messages and send messages.
```Python hl_lines="48 49 50 51 52"
```Python hl_lines="48-52"
{!../../../docs_src/websockets/tutorial001.py!}
```
@@ -98,7 +98,7 @@ In WebSocket endpoints you can import from `fastapi` and use:
They work the same way as for other FastAPI endpoints/*path operations*:
```Python hl_lines="58 59 60 61 62 63 64 65 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83"
```Python hl_lines="58-65 68-83"
{!../../../docs_src/websockets/tutorial002.py!}
```
@@ -137,6 +137,33 @@ With that you can connect the WebSocket and then send and receive messages:
<img src="/img/tutorial/websockets/image05.png">
## Handling disconnections and multiple clients
When a WebSocket connection is closed, the `await websocket.receive_text()` will raise a `WebSocketDisconnect` exception, which you can then catch and handle like in this example.
```Python hl_lines="81-83"
{!../../../docs_src/websockets/tutorial003.py!}
```
To try it out:
* Open the app with several browser tabs.
* Write messages from them.
* Then close one of the tabs.
That will raise the `WebSocketDisconnect` exception, and all the other clients will receive a message like:
```
Client #1596980209979 left the chat
```
!!! tip
The app above is a minimal and simple example to demonstrate how to handle and broadcast messages to several WebSocket connections.
But have in mind that, as everything is handled in memory, in a single list, it will only work while the process is running, and will only work with a single process.
If you need something easy to integrate with FastAPI but that is more robust, supported by Redis, PostgreSQL or others, check <a href="https://github.com/encode/broadcaster" class="external-link" target="_blank">encode/broadcaster</a>.
## More info
To learn more about the options, check Starlette's documentation for:

View File

@@ -12,7 +12,7 @@ Then wrap the WSGI (e.g. Flask) app with the middleware.
And then mount that under a path.
```Python hl_lines="2 3 22"
```Python hl_lines="2-3 22"
{!../../../docs_src/wsgi/tutorial001.py!}
```

View File

@@ -37,7 +37,7 @@ It was one of the first examples of **automatic API documentation**, and this wa
!!! check "Inspired **FastAPI** to"
Have an automatic API documentation web user interface.
### <a href="http://flask.pocoo.org/" class="external-link" target="_blank">Flask</a>
### <a href="https://flask.palletsprojects.com" class="external-link" target="_blank">Flask</a>
Flask is a "microframework", it doesn't include database integrations nor many of the things that come by default in Django.
@@ -57,7 +57,7 @@ Given the simplicity of Flask, it seemed like a good match for building APIs. Th
Have a simple and easy to use routing system.
### <a href="http://docs.python-requests.org" class="external-link" target="_blank">Requests</a>
### <a href="https://requests.readthedocs.io" class="external-link" target="_blank">Requests</a>
**FastAPI** is not actually an alternative to **Requests**. Their scope is very different.
@@ -276,7 +276,7 @@ Routes are declared in a single place, using functions declared in other places
This actually inspired updating parts of Pydantic, to support the same validation declaration style (all this functionality is now already available in Pydantic).
### <a href="http://www.hug.rest/" class="external-link" target="_blank">Hug</a>
### <a href="https://www.hug.rest/" class="external-link" target="_blank">Hug</a>
Hug was one of the first frameworks to implement the declaration of API parameter types using Python type hints. This was a great idea that inspired other tools to do the same.
@@ -410,7 +410,7 @@ It is the recommended server for Starlette and **FastAPI**.
You can combine it with Gunicorn, to have an asynchronous multi-process server.
Check more details in the [Deployment](deployment.md){.internal-link target=_blank} section.
Check more details in the [Deployment](deployment/index.md){.internal-link target=_blank} section.
## Benchmarks and speed

View File

@@ -210,7 +210,7 @@ Most of the existing popular Python frameworks (including Flask and Django) were
Even though the main specification for asynchronous web Python (ASGI) was developed at Django, to add support for WebSockets.
That kind of asynchronicity is what made NodeJS popular (even though NodeJS is not parallel) and that's the strength of Go as a programing language.
That kind of asynchronicity is what made NodeJS popular (even though NodeJS is not parallel) and that's the strength of Go as a programming language.
And that's the same level of performance you get with **FastAPI**.
@@ -261,7 +261,7 @@ But you can also exploit the benefits of parallelism and multiprocessing (having
That, plus the simple fact that Python is the main language for **Data Science**, Machine Learning and especially Deep Learning, make FastAPI a very good match for Data Science / Machine Learning web APIs and applications (among many others).
To see how to achieve this parallelism in production see the section about [Deployment](deployment.md){.internal-link target=_blank}.
To see how to achieve this parallelism in production see the section about [Deployment](deployment/index.md){.internal-link target=_blank}.
## `async` and `await`
@@ -305,7 +305,7 @@ burgers = get_burgers(2)
So, if you are using a library that tells you that you can call it with `await`, you need to create the *path operation functions* that uses it with `async def`, like in:
```Python hl_lines="2 3"
```Python hl_lines="2-3"
@app.get('/burgers')
async def read_burgers():
burgers = await get_burgers(2)
@@ -334,7 +334,7 @@ This same syntax (or almost identical) was also included recently in modern vers
But before that, handling asynchronous code was quite more complex and difficult.
In previous versions of Python, you could have used threads or <a href="http://www.gevent.org/" class="external-link" target="_blank">Gevent</a>. But the code is way more complex to understand, debug, and think about.
In previous versions of Python, you could have used threads or <a href="https://www.gevent.org/" class="external-link" target="_blank">Gevent</a>. But the code is way more complex to understand, debug, and think about.
In previous versions of NodeJS / Browser JavaScript, you would have used "callbacks". Which leads to <a href="http://callbackhell.com/" class="external-link" target="_blank">callback hell</a>.

View File

@@ -10,7 +10,7 @@ When you check the benchmarks, it is common to see several tools of different ty
Specifically, to see Uvicorn, Starlette and FastAPI compared together (among many other tools).
The simplest the problem solved by the tool, the better performance it will get. And most of the benchmarks don't test the additional features provided by the tool.
The simpler the problem solved by the tool, the better performance it will get. And most of the benchmarks don't test the additional features provided by the tool.
The hierarchy is like:

View File

@@ -1,18 +1,57 @@
a.external-link::after {
/* \00A0 is a non-breaking space
/* \00A0 is a non-breaking space
to make the mark be on the same line as the link
*/
content: "\00A0[↪]";
content: "\00A0[↪]";
}
a.internal-link::after {
/* \00A0 is a non-breaking space
/* \00A0 is a non-breaking space
to make the mark be on the same line as the link
*/
content: "\00A0↪";
content: "\00A0↪";
}
/* Give space to lower icons so Gitter chat doesn't get on top of them */
.md-footer-meta {
padding-bottom: 2em;
padding-bottom: 2em;
}
.user-list {
display: flex;
flex-wrap: wrap;
}
.user-list-center {
justify-content: space-evenly;
}
.user {
margin: 1em;
min-width: 7em;
}
.user .avatar-wrapper {
width: 80px;
height: 80px;
margin: 10px auto;
overflow: hidden;
border-radius: 50%;
position: relative;
}
.user .avatar-wrapper img {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.user .title {
text-align: center;
}
.user .count {
font-size: 80%;
text-align: center;
}

View File

@@ -1,396 +0,0 @@
# Deployment
Deploying a **FastAPI** application is relatively easy.
There are several ways to do it depending on your specific use case and the tools that you use.
You will see more about some of the ways to do it in the next sections.
## FastAPI versions
**FastAPI** is already being used in production in many applications and systems. And the test coverage is kept at 100%. But its development is still moving quickly.
New features are added frequently, bugs are fixed regularly, and the code is still continuously improving.
That's why the current versions are still `0.x.x`, this reflects that each version could potentially have breaking changes. This follows the <a href="https://semver.org/" class="external-link" target="_blank">Semantic Versioning</a> conventions.
You can create production applications with **FastAPI** right now (and you have probably been doing it for some time), you just have to make sure that you use a version that works correctly with the rest of your code.
### Pin your `fastapi` version
The first thing you should do is to "pin" the version of **FastAPI** you are using to the specific latest version that you know works correctly for your application.
For example, let's say you are using version `0.45.0` in your app.
If you use a `requirements.txt` file you could specify the version with:
```txt
fastapi==0.45.0
```
that would mean that you would use exactly the version `0.45.0`.
Or you could also pin it with:
```txt
fastapi>=0.45.0,<0.46.0
```
that would mean that you would use the versions `0.45.0` or above, but less than `0.46.0`, for example, a version `0.45.2` would still be accepted.
If you use any other tool to manage your installations, like Poetry, Pipenv, or others, they all have a way that you can use to define specific versions for your packages.
### Available versions
You can see the available versions (e.g. to check what is the current latest) in the [Release Notes](release-notes.md){.internal-link target=_blank}.
### About versions
Following the Semantic Versioning conventions, any version below `1.0.0` could potentially add breaking changes.
FastAPI also follows the convention that any "PATCH" version change is for bug fixes and non-breaking changes.
!!! tip
The "PATCH" is the last number, for example, in `0.2.3`, the PATCH version is `3`.
So, you should be able to pin to a version like:
```txt
fastapi>=0.45.0,<0.46.0
```
Breaking changes and new features are added in "MINOR" versions.
!!! tip
The "MINOR" is the number in the middle, for example, in `0.2.3`, the MINOR version is `2`.
### Upgrading the FastAPI versions
You should add tests for your app.
With **FastAPI** it's very easy (thanks to Starlette), check the docs: [Testing](tutorial/testing.md){.internal-link target=_blank}
After you have tests, then you can upgrade the **FastAPI** version to a more recent one, and make sure that all your code is working correctly by running your tests.
If everything is working, or after you make the necessary changes, and all your tests are passing, then you can pin your `fastapi` to that new recent version.
### About Starlette
You shouldn't pin the version of `starlette`.
Different versions of **FastAPI** will use a specific newer version of Starlette.
So, you can just let **FastAPI** use the correct Starlette version.
### About Pydantic
Pydantic includes the tests for **FastAPI** with its own tests, so new versions of Pydantic (above `1.0.0`) are always compatible with FastAPI.
You can pin Pydantic to any version above `1.0.0` that works for you and below `2.0.0`.
For example:
```txt
pydantic>=1.2.0,<2.0.0
```
## Docker
In this section you'll see instructions and links to guides to know how to:
* Make your **FastAPI** application a Docker image/container with maximum performance. In about **5 min**.
* (Optionally) understand what you, as a developer, need to know about HTTPS.
* Set up a Docker Swarm mode cluster with automatic HTTPS, even on a simple $5 USD/month server. In about **20 min**.
* Generate and deploy a full **FastAPI** application, using your Docker Swarm cluster, with HTTPS, etc. In about **10 min**.
You can use <a href="https://www.docker.com/" class="external-link" target="_blank">**Docker**</a> for deployment. It has several advantages like security, replicability, development simplicity, etc.
If you are using Docker, you can use the official Docker image:
### <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>
This image has an "auto-tuning" mechanism included, so that you can just add your code and get very high performance automatically. And without making sacrifices.
But you can still change and update all the configurations with environment variables or configuration files.
!!! tip
To see all the configurations and options, go to the Docker image page: <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>.
### Create a `Dockerfile`
* Go to your project directory.
* Create a `Dockerfile` with:
```Dockerfile
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
COPY ./app /app
```
#### Bigger Applications
If you followed the section about creating [Bigger Applications with Multiple Files](tutorial/bigger-applications.md){.internal-link target=_blank}, your `Dockerfile` might instead look like:
```Dockerfile
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
COPY ./app /app/app
```
#### Raspberry Pi and other architectures
If you are running Docker in a Raspberry Pi (that has an ARM processor) or any other architecture, you can create a `Dockerfile` from scratch, based on a Python base image (that is multi-architecture) and use Uvicorn alone.
In this case, your `Dockerfile` could look like:
```Dockerfile
FROM python:3.7
RUN pip install fastapi uvicorn
EXPOSE 80
COPY ./app /app
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
```
### Create the **FastAPI** Code
* Create an `app` directory and enter in it.
* Create a `main.py` file with:
```Python
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "q": q}
```
* You should now have a directory structure like:
```
.
├── app
│ └── main.py
└── Dockerfile
```
### Build the Docker image
* Go to the project directory (in where your `Dockerfile` is, containing your `app` directory).
* Build your FastAPI image:
<div class="termy">
```console
$ docker build -t myimage .
---> 100%
```
</div>
### Start the Docker container
* Run a container based on your image:
<div class="termy">
```console
$ docker run -d --name mycontainer -p 80:80 myimage
```
</div>
Now you have an optimized FastAPI server in a Docker container. Auto-tuned for your current server (and number of CPU cores).
### Check it
You should be able to check it in your Docker container's URL, for example: <a href="http://192.168.99.100/items/5?q=somequery" class="external-link" target="_blank">http://192.168.99.100/items/5?q=somequery</a> or <a href="http://127.0.0.1/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1/items/5?q=somequery</a> (or equivalent, using your Docker host).
You will see something like:
```JSON
{"item_id": 5, "q": "somequery"}
```
### Interactive API docs
Now you can go to <a href="http://192.168.99.100/docs" class="external-link" target="_blank">http://192.168.99.100/docs</a> or <a href="http://127.0.0.1/docs" class="external-link" target="_blank">http://127.0.0.1/docs</a> (or equivalent, using your Docker host).
You will see the automatic interactive API documentation (provided by <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
### Alternative API docs
And you can also go to <a href="http://192.168.99.100/redoc" class="external-link" target="_blank">http://192.168.99.100/redoc</a> or <a href="http://127.0.0.1/redoc" class="external-link" target="_blank">http://127.0.0.1/redoc</a> (or equivalent, using your Docker host).
You will see the alternative automatic documentation (provided by <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>):
![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
## HTTPS
### About HTTPS
It is easy to assume that HTTPS is something that is just "enabled" or not.
But it is way more complex than that.
!!! tip
If you are in a hurry or don't care, continue with the next section for step by step instructions to set everything up.
To learn the basics of HTTPS, from a consumer perspective, check <a href="https://howhttps.works/" class="external-link" target="_blank">https://howhttps.works/</a>.
Now, from a developer's perspective, here are several things to have in mind while thinking about HTTPS:
* For HTTPS, the server needs to have "certificates" generated by a third party.
* Those certificates are actually acquired from the third-party, not "generated".
* Certificates have a lifetime.
* They expire.
* And then they need to be renewed, acquired again from the third party.
* The encryption of the connection happens at the TCP level.
* That's one layer below HTTP.
* So, the certificate and encryption handling is done before HTTP.
* TCP doesn't know about "domains". Only about IP addresses.
* The information about the specific domain requested goes in the HTTP data.
* The HTTPS certificates "certify" a certain domain, but the protocol and encryption happen at the TCP level, before knowing which domain is being dealt with.
* By default, that would mean that you can only have one HTTPS certificate per IP address.
* No matter how big your server is or how small each application you have on it might be.
* There is a solution to this, however.
* There's an extension to the TLS protocol (the one handling the encryption at the TCP level, before HTTP) called <a href="https://en.wikipedia.org/wiki/Server_Name_Indication" class="external-link" target="_blank"><abbr title="Server Name Indication">SNI</abbr></a>.
* This SNI extension allows one single server (with a single IP address) to have several HTTPS certificates and serve multiple HTTPS domains/applications.
* For this to work, a single component (program) running on the server, listening on the public IP address, must have all the HTTPS certificates in the server.
* After obtaining a secure connection, the communication protocol is still HTTP.
* The contents are encrypted, even though they are being sent with the HTTP protocol.
It is a common practice to have one program/HTTP server running on the server (the machine, host, etc.) and managing all the HTTPS parts : sending the decrypted HTTP requests to the actual HTTP application running in the same server (the **FastAPI** application, in this case), take the HTTP response from the application, encrypt it using the appropriate certificate and sending it back to the client using HTTPS. This server is often called a <a href="https://en.wikipedia.org/wiki/TLS_termination_proxy" class="external-link" target="_blank">TLS Termination Proxy</a>.
### Let's Encrypt
Before Let's Encrypt, these HTTPS certificates were sold by trusted third-parties.
The process to acquire one of these certificates used to be cumbersome, require quite some paperwork and the certificates were quite expensive.
But then <a href="https://letsencrypt.org/" class="external-link" target="_blank">Let's Encrypt</a> was created.
It is a project from the Linux Foundation. It provides HTTPS certificates for free. In an automated way. These certificates use all the standard cryptographic security, and are short lived (about 3 months), so the security is actually better because of their reduced lifespan.
The domains are securely verified and the certificates are generated automatically. This also allows automating the renewal of these certificates.
The idea is to automate the acquisition and renewal of these certificates, so that you can have secure HTTPS, for free, forever.
### Traefik
<a href="https://traefik.io/" class="external-link" target="_blank">Traefik</a> is a high performance reverse proxy / load balancer. It can do the "TLS Termination Proxy" job (apart from other features).
It has integration with Let's Encrypt. So, it can handle all the HTTPS parts, including certificate acquisition and renewal.
It also has integrations with Docker. So, you can declare your domains in each application configurations and have it read those configurations, generate the HTTPS certificates and serve HTTPS to your application automatically, without requiring any change in its configuration.
---
With this information and tools, continue with the next section to combine everything.
## Docker Swarm mode cluster with Traefik and HTTPS
You can have a Docker Swarm mode cluster set up in minutes (about 20 min) with a main Traefik handling HTTPS (including certificate acquisition and renewal).
By using Docker Swarm mode, you can start with a "cluster" of a single machine (it can even be a $5 USD / month server) and then you can grow as much as you need adding more servers.
To set up a Docker Swarm Mode cluster with Traefik and HTTPS handling, follow this guide:
### <a href="https://medium.com/@tiangolo/docker-swarm-mode-and-traefik-for-a-https-cluster-20328dba6232" class="external-link" target="_blank">Docker Swarm Mode and Traefik for an HTTPS cluster</a>
### Deploy a FastAPI application
The easiest way to set everything up, would be using the [**FastAPI** Project Generators](project-generation.md){.internal-link target=_blank}.
It is designed to be integrated with this Docker Swarm cluster with Traefik and HTTPS described above.
You can generate a project in about 2 min.
The generated project has instructions to deploy it, doing it takes another 2 min.
## Alternatively, deploy **FastAPI** without Docker
You can deploy **FastAPI** directly without Docker too.
You just need to install an ASGI compatible server like:
=== "Uvicorn"
* <a href="https://www.uvicorn.org/" class="external-link" target="_blank">Uvicorn</a>, a lightning-fast ASGI server, built on uvloop and httptools.
<div class="termy">
```console
$ pip install uvicorn
---> 100%
```
</div>
=== "Hypercorn"
* <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>, an ASGI server also compatible with HTTP/2.
<div class="termy">
```console
$ pip install hypercorn
---> 100%
```
</div>
...or any other ASGI server.
And run your application the same way you have done in the tutorials, but without the `--reload` option, e.g.:
=== "Uvicorn"
<div class="termy">
```console
$ uvicorn main:app --host 0.0.0.0 --port 80
<span style="color: green;">INFO</span>: Uvicorn running on http://0.0.0.0:80 (Press CTRL+C to quit)
```
</div>
=== "Hypercorn"
<div class="termy">
```console
$ hypercorn main:app --bind 0.0.0.0:80
Running on 0.0.0.0:8080 over http (CTRL + C to quit)
```
</div>
You might want to set up some tooling to make sure it is restarted automatically if it stops.
You might also want to install <a href="https://gunicorn.org/" class="external-link" target="_blank">Gunicorn</a> and <a href="https://www.uvicorn.org/#running-with-gunicorn" class="external-link" target="_blank">use it as a manager for Uvicorn</a>, or use Hypercorn with multiple workers.
Making sure to fine-tune the number of workers, etc.
But if you are doing all that, you might just use the Docker image that does it automatically.

View File

@@ -0,0 +1,240 @@
# Deploy on Deta
In this section you will learn how to easily deploy a **FastAPI** application on <a href="https://www.deta.sh/?ref=fastapi" class="external-link" target="_blank">Deta</a> using the free plan. 🎁
It will take you about **10 minutes**.
!!! info
<a href="https://www.deta.sh/?ref=fastapi" class="external-link" target="_blank">Deta</a> is a **FastAPI** sponsor. 🎉
## A basic **FastAPI** app
* Create a directory for your app, for example `./fastapideta/` and enter in it.
### FastAPI code
* Create a `main.py` file with:
```Python
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int):
return {"item_id": item_id}
```
### Requirements
Now, in the same directory create a file `requirements.txt` with:
```text
fastapi
```
!!! tip
You don't need to install Uvicorn to deploy on Deta, although you would probably want to install it locally to test your app.
### Directory structure
You will now have one directory `./fastapideta/` with two files:
```
.
└── main.py
└── requirements.txt
```
## Create a free Deta account
Now create a <a href="https://www.deta.sh/?ref=fastapi" class="external-link" target="_blank">free account on Deta</a>, you just need an email and password.
You don't even need a credit card.
## Install the CLI
Once you have your account, install the Deta <abbr title="Command Line Interface application">CLI</abbr>:
=== "Linux, macOS"
<div class="termy">
```console
$ curl -fsSL https://get.deta.dev/cli.sh | sh
```
</div>
=== "Windows PowerShell"
<div class="termy">
```console
$ iwr https://get.deta.dev/cli.ps1 -useb | iex
```
</div>
After installing it, open a new terminal so that the installed CLI is detected.
In a new terminal, confirm that it was correctly installed with:
<div class="termy">
```console
$ deta --help
Deta command line interface for managing deta micros.
Complete documentation available at https://docs.deta.sh
Usage:
deta [flags]
deta [command]
Available Commands:
auth Change auth settings for a deta micro
...
```
</div>
!!! tip
If you have problems installing the CLI, check the <a href="https://docs.deta.sh/docs/micros/getting_started?ref=fastapi" class="external-link" target="_blank">official Deta docs</a>.
## Login with the CLI
Now login to Deta from the CLI with:
<div class="termy">
```console
$ deta login
Please, log in from the web page. Waiting..
Logged in successfully.
```
</div>
This will open a web browser and authenticate automatically.
## Deploy with Deta
Next, deploy your application with the Deta CLI:
<div class="termy">
```console
$ deta new
Successfully created a new micro
// Notice the "endpoint" 🔍
{
"name": "fastapideta",
"runtime": "python3.7",
"endpoint": "https://qltnci.deta.dev",
"visor": "enabled",
"http_auth": "enabled"
}
Adding dependencies...
---> 100%
Successfully installed fastapi-0.61.1 pydantic-1.7.2 starlette-0.13.6
```
</div>
You will see a JSON message similar to:
```JSON hl_lines="4"
{
"name": "fastapideta",
"runtime": "python3.7",
"endpoint": "https://qltnci.deta.dev",
"visor": "enabled",
"http_auth": "enabled"
}
```
!!! tip
Your deployment will have a different `"endpoint"` URL.
## Check it
Now open your browser in your `endpoint` URL. In the example above it was `https://qltnci.deta.dev`, but yours will be different.
You will see the JSON response from your FastAPI app:
```JSON
{
"Hello": "World"
}
```
And now go to the `/docs` for your API, in the example above it would be `https://qltnci.deta.dev/docs`.
It will show your docs like:
<img src="/img/deployment/deta/image01.png">
## Enable public access
By default, Deta will handle authentication using cookies for your account.
But once you are ready, you can make it public with:
<div class="termy">
```console
$ deta auth disable
Successfully disabled http auth
```
</div>
Now you can share that URL with anyone and they will be able to access your API. 🚀
## HTTPS
Congrats! You deployed your FastAPI app to Deta! 🎉 🍰
Also notice that Deta correctly handles HTTPS for you, so you don't have to take care of that and can be sure that your clients will have a secure encrypted connection. ✅ 🔒
## Check the Visor
From your docs UI (they will be in a URL like `https://qltnci.deta.dev/docs`) send a request to your *path operation* `/items/{item_id}`.
For example with ID `5`.
Now go to <a href="https://web.deta.sh/" class="external-link" target="_blank">https://web.deta.sh</a>.
You will see there's a section to the left called <abbr title="it comes from Micro(server)">"Micros"</abbr> with each of your apps.
You will see a tab with "Details", and also a tab "Visor", go to the tab "Visor".
In there you can inspect the recent requests sent to your app.
You can also edit them and re-play them.
<img src="/img/deployment/deta/image02.png">
## Learn more
At some point you will probably want to store some data for your app in a way that persists through time. For that you can use <a href="https://docs.deta.sh/docs/base/py_tutorial?ref=fastapi" class="external-link" target="_blank">Deta Base</a>, it also has a generous **free tier**.
You can also read more in the <a href="https://docs.deta.sh?ref=fastapi" class="external-link" target="_blank">Deta Docs</a>.

View File

@@ -0,0 +1,179 @@
# Deploy with Docker
In this section you'll see instructions and links to guides to know how to:
* Make your **FastAPI** application a Docker image/container with maximum performance. In about **5 min**.
* (Optionally) understand what you, as a developer, need to know about HTTPS.
* Set up a Docker Swarm mode cluster with automatic HTTPS, even on a simple $5 USD/month server. In about **20 min**.
* Generate and deploy a full **FastAPI** application, using your Docker Swarm cluster, with HTTPS, etc. In about **10 min**.
You can use <a href="https://www.docker.com/" class="external-link" target="_blank">**Docker**</a> for deployment. It has several advantages like security, replicability, development simplicity, etc.
If you are using Docker, you can use the official Docker image:
## <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>
This image has an "auto-tuning" mechanism included, so that you can just add your code and get very high performance automatically. And without making sacrifices.
But you can still change and update all the configurations with environment variables or configuration files.
!!! tip
To see all the configurations and options, go to the Docker image page: <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>.
## Create a `Dockerfile`
* Go to your project directory.
* Create a `Dockerfile` with:
```Dockerfile
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
COPY ./app /app
```
### Bigger Applications
If you followed the section about creating [Bigger Applications with Multiple Files](../tutorial/bigger-applications.md){.internal-link target=_blank}, your `Dockerfile` might instead look like:
```Dockerfile
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
COPY ./app /app/app
```
### Raspberry Pi and other architectures
If you are running Docker in a Raspberry Pi (that has an ARM processor) or any other architecture, you can create a `Dockerfile` from scratch, based on a Python base image (that is multi-architecture) and use Uvicorn alone.
In this case, your `Dockerfile` could look like:
```Dockerfile
FROM python:3.7
RUN pip install fastapi uvicorn
EXPOSE 80
COPY ./app /app
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
```
## Create the **FastAPI** Code
* Create an `app` directory and enter in it.
* Create a `main.py` file with:
```Python
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "q": q}
```
* You should now have a directory structure like:
```
.
├── app
│ └── main.py
└── Dockerfile
```
## Build the Docker image
* Go to the project directory (in where your `Dockerfile` is, containing your `app` directory).
* Build your FastAPI image:
<div class="termy">
```console
$ docker build -t myimage .
---> 100%
```
</div>
## Start the Docker container
* Run a container based on your image:
<div class="termy">
```console
$ docker run -d --name mycontainer -p 80:80 myimage
```
</div>
Now you have an optimized FastAPI server in a Docker container. Auto-tuned for your current server (and number of CPU cores).
## Check it
You should be able to check it in your Docker container's URL, for example: <a href="http://192.168.99.100/items/5?q=somequery" class="external-link" target="_blank">http://192.168.99.100/items/5?q=somequery</a> or <a href="http://127.0.0.1/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1/items/5?q=somequery</a> (or equivalent, using your Docker host).
You will see something like:
```JSON
{"item_id": 5, "q": "somequery"}
```
## Interactive API docs
Now you can go to <a href="http://192.168.99.100/docs" class="external-link" target="_blank">http://192.168.99.100/docs</a> or <a href="http://127.0.0.1/docs" class="external-link" target="_blank">http://127.0.0.1/docs</a> (or equivalent, using your Docker host).
You will see the automatic interactive API documentation (provided by <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
## Alternative API docs
And you can also go to <a href="http://192.168.99.100/redoc" class="external-link" target="_blank">http://192.168.99.100/redoc</a> or <a href="http://127.0.0.1/redoc" class="external-link" target="_blank">http://127.0.0.1/redoc</a> (or equivalent, using your Docker host).
You will see the alternative automatic documentation (provided by <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>):
![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
## Traefik
<a href="https://traefik.io/" class="external-link" target="_blank">Traefik</a> is a high performance reverse proxy / load balancer. It can do the "TLS Termination Proxy" job (apart from other features).
It has integration with Let's Encrypt. So, it can handle all the HTTPS parts, including certificate acquisition and renewal.
It also has integrations with Docker. So, you can declare your domains in each application configurations and have it read those configurations, generate the HTTPS certificates and serve HTTPS to your application automatically, without requiring any change in its configuration.
---
With this information and tools, continue with the next section to combine everything.
## Docker Swarm mode cluster with Traefik and HTTPS
You can have a Docker Swarm mode cluster set up in minutes (about 20 min) with a main Traefik handling HTTPS (including certificate acquisition and renewal).
By using Docker Swarm mode, you can start with a "cluster" of a single machine (it can even be a $5 USD / month server) and then you can grow as much as you need adding more servers.
To set up a Docker Swarm Mode cluster with Traefik and HTTPS handling, follow this guide:
### <a href="https://medium.com/@tiangolo/docker-swarm-mode-and-traefik-for-a-https-cluster-20328dba6232" class="external-link" target="_blank">Docker Swarm Mode and Traefik for an HTTPS cluster</a>
### Deploy a FastAPI application
The easiest way to set everything up, would be using the [**FastAPI** Project Generators](../project-generation.md){.internal-link target=_blank}.
It is designed to be integrated with this Docker Swarm cluster with Traefik and HTTPS described above.
You can generate a project in about 2 min.
The generated project has instructions to deploy it, doing it takes another 2 min.

View File

@@ -0,0 +1,48 @@
# About HTTPS
It is easy to assume that HTTPS is something that is just "enabled" or not.
But it is way more complex than that.
!!! tip
If you are in a hurry or don't care, continue with the next sections for step by step instructions to set everything up with different techniques.
To learn the basics of HTTPS, from a consumer perspective, check <a href="https://howhttps.works/" class="external-link" target="_blank">https://howhttps.works/</a>.
Now, from a developer's perspective, here are several things to have in mind while thinking about HTTPS:
* For HTTPS, the server needs to have "certificates" generated by a third party.
* Those certificates are actually acquired from the third-party, not "generated".
* Certificates have a lifetime.
* They expire.
* And then they need to be renewed, acquired again from the third party.
* The encryption of the connection happens at the TCP level.
* That's one layer below HTTP.
* So, the certificate and encryption handling is done before HTTP.
* TCP doesn't know about "domains". Only about IP addresses.
* The information about the specific domain requested goes in the HTTP data.
* The HTTPS certificates "certify" a certain domain, but the protocol and encryption happen at the TCP level, before knowing which domain is being dealt with.
* By default, that would mean that you can only have one HTTPS certificate per IP address.
* No matter how big your server is or how small each application you have on it might be.
* There is a solution to this, however.
* There's an extension to the TLS protocol (the one handling the encryption at the TCP level, before HTTP) called <a href="https://en.wikipedia.org/wiki/Server_Name_Indication" class="external-link" target="_blank"><abbr title="Server Name Indication">SNI</abbr></a>.
* This SNI extension allows one single server (with a single IP address) to have several HTTPS certificates and serve multiple HTTPS domains/applications.
* For this to work, a single component (program) running on the server, listening on the public IP address, must have all the HTTPS certificates in the server.
* After obtaining a secure connection, the communication protocol is still HTTP.
* The contents are encrypted, even though they are being sent with the HTTP protocol.
It is a common practice to have one program/HTTP server running on the server (the machine, host, etc.) and managing all the HTTPS parts : sending the decrypted HTTP requests to the actual HTTP application running in the same server (the **FastAPI** application, in this case), take the HTTP response from the application, encrypt it using the appropriate certificate and sending it back to the client using HTTPS. This server is often called a <a href="https://en.wikipedia.org/wiki/TLS_termination_proxy" class="external-link" target="_blank">TLS Termination Proxy</a>.
## Let's Encrypt
Before Let's Encrypt, these HTTPS certificates were sold by trusted third-parties.
The process to acquire one of these certificates used to be cumbersome, require quite some paperwork and the certificates were quite expensive.
But then <a href="https://letsencrypt.org/" class="external-link" target="_blank">Let's Encrypt</a> was created.
It is a project from the Linux Foundation. It provides HTTPS certificates for free. In an automated way. These certificates use all the standard cryptographic security, and are short lived (about 3 months), so the security is actually better because of their reduced lifespan.
The domains are securely verified and the certificates are generated automatically. This also allows automating the renewal of these certificates.
The idea is to automate the acquisition and renewal of these certificates, so that you can have secure HTTPS, for free, forever.

View File

@@ -0,0 +1,7 @@
# Deployment - Intro
Deploying a **FastAPI** application is relatively easy.
There are several ways to do it depending on your specific use case and the tools that you use.
You will see more details to have in mind and some of the techniques to do it in the next sections.

View File

@@ -0,0 +1,69 @@
# Deploy manually
You can deploy **FastAPI** manually as well.
You just need to install an ASGI compatible server like:
=== "Uvicorn"
* <a href="https://www.uvicorn.org/" class="external-link" target="_blank">Uvicorn</a>, a lightning-fast ASGI server, built on uvloop and httptools.
<div class="termy">
```console
$ pip install uvicorn
---> 100%
```
</div>
=== "Hypercorn"
* <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>, an ASGI server also compatible with HTTP/2.
<div class="termy">
```console
$ pip install hypercorn
---> 100%
```
</div>
...or any other ASGI server.
And run your application the same way you have done in the tutorials, but without the `--reload` option, e.g.:
=== "Uvicorn"
<div class="termy">
```console
$ uvicorn main:app --host 0.0.0.0 --port 80
<span style="color: green;">INFO</span>: Uvicorn running on http://0.0.0.0:80 (Press CTRL+C to quit)
```
</div>
=== "Hypercorn"
<div class="termy">
```console
$ hypercorn main:app --bind 0.0.0.0:80
Running on 0.0.0.0:8080 over http (CTRL + C to quit)
```
</div>
You might want to set up some tooling to make sure it is restarted automatically if it stops.
You might also want to install <a href="https://gunicorn.org/" class="external-link" target="_blank">Gunicorn</a> and <a href="https://www.uvicorn.org/#running-with-gunicorn" class="external-link" target="_blank">use it as a manager for Uvicorn</a>, or use Hypercorn with multiple workers.
Making sure to fine-tune the number of workers, etc.
But if you are doing all that, you might just use the Docker image that does it automatically.

View File

@@ -0,0 +1,87 @@
# About FastAPI versions
**FastAPI** is already being used in production in many applications and systems. And the test coverage is kept at 100%. But its development is still moving quickly.
New features are added frequently, bugs are fixed regularly, and the code is still continuously improving.
That's why the current versions are still `0.x.x`, this reflects that each version could potentially have breaking changes. This follows the <a href="https://semver.org/" class="external-link" target="_blank">Semantic Versioning</a> conventions.
You can create production applications with **FastAPI** right now (and you have probably been doing it for some time), you just have to make sure that you use a version that works correctly with the rest of your code.
## Pin your `fastapi` version
The first thing you should do is to "pin" the version of **FastAPI** you are using to the specific latest version that you know works correctly for your application.
For example, let's say you are using version `0.45.0` in your app.
If you use a `requirements.txt` file you could specify the version with:
```txt
fastapi==0.45.0
```
that would mean that you would use exactly the version `0.45.0`.
Or you could also pin it with:
```txt
fastapi>=0.45.0,<0.46.0
```
that would mean that you would use the versions `0.45.0` or above, but less than `0.46.0`, for example, a version `0.45.2` would still be accepted.
If you use any other tool to manage your installations, like Poetry, Pipenv, or others, they all have a way that you can use to define specific versions for your packages.
## Available versions
You can see the available versions (e.g. to check what is the current latest) in the [Release Notes](../release-notes.md){.internal-link target=_blank}.
## About versions
Following the Semantic Versioning conventions, any version below `1.0.0` could potentially add breaking changes.
FastAPI also follows the convention that any "PATCH" version change is for bug fixes and non-breaking changes.
!!! tip
The "PATCH" is the last number, for example, in `0.2.3`, the PATCH version is `3`.
So, you should be able to pin to a version like:
```txt
fastapi>=0.45.0,<0.46.0
```
Breaking changes and new features are added in "MINOR" versions.
!!! tip
The "MINOR" is the number in the middle, for example, in `0.2.3`, the MINOR version is `2`.
## Upgrading the FastAPI versions
You should add tests for your app.
With **FastAPI** it's very easy (thanks to Starlette), check the docs: [Testing](../tutorial/testing.md){.internal-link target=_blank}
After you have tests, then you can upgrade the **FastAPI** version to a more recent one, and make sure that all your code is working correctly by running your tests.
If everything is working, or after you make the necessary changes, and all your tests are passing, then you can pin your `fastapi` to that new recent version.
## About Starlette
You shouldn't pin the version of `starlette`.
Different versions of **FastAPI** will use a specific newer version of Starlette.
So, you can just let **FastAPI** use the correct Starlette version.
## About Pydantic
Pydantic includes the tests for **FastAPI** with its own tests, so new versions of Pydantic (above `1.0.0`) are always compatible with FastAPI.
You can pin Pydantic to any version above `1.0.0` that works for you and below `2.0.0`.
For example:
```txt
pydantic>=1.2.0,<2.0.0
```

View File

@@ -0,0 +1,155 @@
# FastAPI People
FastAPI has an amazing community that welcomes people from all backgrounds.
## Creator - Maintainer
Hey! 👋
This is me:
{% if people %}
<div class="user-list user-list-center">
{% for user in people.maintainers %}
<div class="user"><a href="{{ user.url }}" target="_blank"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Answers: {{ user.answers }}</div><div class="count">Pull Requests: {{ user.prs }}</div></div>
{% endfor %}
</div>
{% endif %}
I'm the creator and maintainer of **FastAPI**. You can read more about that in [Help FastAPI - Get Help - Connect with the author](help-fastapi.md#connect-with-the-author){.internal-link target=_blank}.
...But here I want to show you the community.
---
**FastAPI** receives a lot of support from the community. And I want to highlight their contributions.
These are the people that:
* [Help others with issues (questions) in GitHub](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank}.
* [Create Pull Requests](help-fastapi.md#create-a-pull-request){.internal-link target=_blank}.
* Review Pull Requests, [especially important for translations](contributing.md#translations){.internal-link target=_blank}.
A round of applause to them. 👏 🙇
## Most active users last month
These are the users that have been [helping others the most with issues (questions) in GitHub](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank} during the last month. ☕
{% if people %}
<div class="user-list user-list-center">
{% for user in people.last_month_active %}
<div class="user"><a href="{{ user.url }}" target="_blank"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Issues replied: {{ user.count }}</div></div>
{% endfor %}
</div>
{% endif %}
## Experts
Here are the **FastAPI Experts**. 🤓
These are the users that have [helped others the most with issues (questions) in GitHub](help-fastapi.md#help-others-with-issues-in-github){.internal-link target=_blank} through *all time*.
They have proven to be experts by helping many others. ✨
{% if people %}
<div class="user-list user-list-center">
{% for user in people.experts %}
<div class="user"><a href="{{ user.url }}" target="_blank"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Issues replied: {{ user.count }}</div></div>
{% endfor %}
</div>
{% endif %}
## Top Contributors
Here are the **Top Contributors**. 👷
These users have [created the most Pull Requests](help-fastapi.md#create-a-pull-request){.internal-link target=_blank} that have been *merged*.
They have contributed source code, documentation, translations, etc. 📦
{% if people %}
<div class="user-list user-list-center">
{% for user in people.top_contributors %}
<div class="user"><a href="{{ user.url }}" target="_blank"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Pull Requests: {{ user.count }}</div></div>
{% endfor %}
</div>
{% endif %}
There are many other contributors (more than a hundred), you can see them all in the <a href="https://github.com/tiangolo/fastapi/graphs/contributors" class="external-link" target="_blank">FastAPI GitHub Contributors page</a>. 👷
## Top Reviewers
These users are the **Top Reviewers**. 🕵️
### Reviews for Translations
I only speak a few languages (and not very well 😅). So, the reviewers are the ones that have the [**power to approve translations**](contributing.md#translations){.internal-link target=_blank} of the documentation. Without them, there wouldn't be documentation in several other languages.
---
The **Top Reviewers** 🕵️ have reviewed the most Pull Requests from others, ensuring the quality of the code, documentation, and especially, the **translations**.
{% if people %}
<div class="user-list user-list-center">
{% for user in people.top_reviewers %}
<div class="user"><a href="{{ user.url }}" target="_blank"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a> <div class="count">Reviews: {{ user.count }}</div></div>
{% endfor %}
</div>
{% endif %}
## Sponsors
These are the **Sponsors**. 😎
They are supporting my work with **FastAPI** (and others), mainly through <a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub Sponsors</a>.
### Gold Sponsors
{% if sponsors %}
{% for sponsor in sponsors.gold -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
{% endfor %}
{% endif %}
### Silver Sponsors
{% if sponsors %}
{% for sponsor in sponsors.silver -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
{% endfor %}
{% endif %}
### Individual Sponsors
{% if people %}
<div class="user-list user-list-center">
{% for user in people.sponsors %}
<div class="user"><a href="{{ user.url }}" target="_blank"><div class="avatar-wrapper"><img src="{{ user.avatarUrl }}"/></div><div class="title">@{{ user.login }}</div></a></div>
{% endfor %}
</div>
{% endif %}
## About the data - technical details
The main intention of this page is to highlight the effort of the community to help others.
Especially including efforts that are normally less visible, and in many cases more arduous, like helping others with issues and reviewing Pull Requests with translations.
The data is calculated each month, you can read the <a href="https://github.com/tiangolo/fastapi/blob/master/.github/actions/people/app/main.py" class="external-link" target="_blank">source code here</a>.
Here I'm also highlighting contributions from sponsors.
I also reserve the right to update the algorithm, sections, thresholds, etc (just in case 🤷).

View File

@@ -7,7 +7,7 @@
### Based on open standards
* <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a> for API creation, including declarations of <abbr title="also known as: endpoints, routes">path</abbr> <abbr title="also known as HTTP methods, as POST, GET, PUT, DELETE">operations</abbr>, parameters, body requests, security, etc.
* Automatic data model documentation with <a href="http://json-schema.org/" class="external-link" target="_blank"><strong>JSON Schema</strong></a> (as OpenAPI itself is based on JSON Schema).
* Automatic data model documentation with <a href="https://json-schema.org/" class="external-link" target="_blank"><strong>JSON Schema</strong></a> (as OpenAPI itself is based on JSON Schema).
* Designed around these standards, after a meticulous study. Instead of an afterthought layer on top.
* This also allows using automatic **client code generation** in many languages.

View File

@@ -52,12 +52,13 @@ I love to hear about how **FastAPI** is being used, what have you liked in it, i
* <a href="https://www.slant.co/options/34241/~fastapi-review" class="external-link" target="_blank">Vote for **FastAPI** in Slant</a>.
* <a href="https://alternativeto.net/software/fastapi/" class="external-link" target="_blank">Vote for **FastAPI** in AlternativeTo</a>.
* <a href="https://github.com/marmelab/awesome-rest/pull/93" class="external-link" target="_blank">Vote for **FastAPI** on awesome-rest</a>.
## Help others with issues in GitHub
You can see <a href="https://github.com/tiangolo/fastapi/issues" class="external-link" target="_blank">existing issues</a> and try and help others, most of the times they are questions that you might already know the answer for. 🤓
If you are helping a lot of people on issues you might become an official [FastAPI Expert](fastapi-people.md#experts){.internal-link target=_blank}. 🎉
## Watch the GitHub repository
You can "watch" FastAPI in GitHub (clicking the "watch" button at the top right): <a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>. 👀
@@ -70,43 +71,52 @@ Then you can try and help them solving those issues.
You can <a href="https://github.com/tiangolo/fastapi/issues/new/choose" class="external-link" target="_blank">create a new issue</a> in the GitHub repository, for example to:
* Ask a question or ask about a problem.
* Suggest a new feature.
* Ask a **question** or ask about a **problem**.
* Suggest a new **feature**.
**Note**: if you create an issue then I'm going to ask you to also help others. 😉
## Create a Pull Request
You can <a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">create a Pull Request</a>, for example:
You can [contribute](contributing.md){.internal-link target=_blank} to the source code with Pull Requests, for example:
* To fix a typo you found on the documentation.
* To share an article, video, or podcast you created or found about FastAPI by <a href="https://github.com/tiangolo/fastapi/edit/master/docs/en/data/external_links.yml" class="external-link" target="_blank">editing this file</a>.
* Make sure you add your link to the end of the corresponding section.
* To help [translate the documentation](contributing.md#translations){.internal-link target=_blank} to your language.
* You can also help reviewing the translations created by others.
* To propose new documentation sections.
* To fix an existing issue/bug.
* To add a new feature.
## Join the chat
<a href="https://gitter.im/tiangolo/fastapi?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge" target="_blank">
<img src="https://badges.gitter.im/tiangolo/fastapi.svg" alt="Join the chat at https://gitter.im/tiangolo/fastapi">
</a>
Join the 👥 <a href="https://discord.gg/VQjSZaeJmf" class="external-link" target="_blank">Discord chat server</a> 👥 and hang out with others in the FastAPI community.
Join the chat on Gitter: <a href="https://gitter.im/tiangolo/fastapi" class="external-link" target="_blank">https://gitter.im/tiangolo/fastapi</a>.
!!! tip
For questions, ask them in <a href="https://github.com/tiangolo/fastapi/issues/new/choose" class="external-link" target="_blank">GitHub issues</a>, there's a much better chance you will receive help by the [FastAPI Experts](fastapi-people.md#experts){.internal-link target=_blank}.
There you can have quick conversations with others, help others, share ideas, etc.
Use the chat only for other general conversations.
But have in mind that as it allows more "free conversation", it's easy to ask questions that are too general and more difficult to answer, so, you might not receive answers.
There is also the previous <a href="https://gitter.im/tiangolo/fastapi" class="external-link" target="_blank">Gitter chat</a>, but as it doesn't have channels and advanced features, conversations are more difficult, so Discord is now the recommended system.
In GitHub issues the template will guide to to write the right question so that you can more easily get a good answer, or even solve the problem yourself even before asking. And in GitHub I can make sure I always answer everything, even if it takes some time. I can't personally do that with the Gitter chat. 😅
### Don't use the chat for questions
Conversations in Gitter are also not as easily searchable as in GitHub, so questions and answers might get lost in the conversation.
Have in mind that as chats allow more "free conversation", it's easy to ask questions that are too general and more difficult to answer, so, you might not receive answers.
On the other side, there's more than 1000 people in the chat, so there's a high chance you'll find someone to talk to there, almost all the time. 😄
In GitHub issues the template will guide you to write the right question so that you can more easily get a good answer, or even solve the problem yourself even before asking. And in GitHub I can make sure I always answer everything, even if it takes some time. I can't personally do that with the chat systems. 😅
Conversations in the chat systems are also not as easily searchable as in GitHub, so questions and answers might get lost in the conversation. And only the ones in GitHub issues count to become a [FastAPI Expert](fastapi-people.md#experts){.internal-link target=_blank}, so you will most probably receive more attention in GitHub isssues.
On the other side, there are thousands of users in the chat systems, so there's a high chance you'll find someone to talk to there, almost all the time. 😄
## Sponsor the author
You can also financially support the author (me) through <a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub sponsors</a>.
There you could buy me a coffee ☕️ to say thanks 😄.
There you could buy me a coffee ☕️ to say thanks. 😄
And you can also become a Silver or Gold sponsor for FastAPI. 🏅🎉
## Sponsor the tools that power FastAPI

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
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"
version="1.1"
id="svg19">
<metadata
id="metadata23">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs17">
<rect
x="-491.25317"
y="-261.21402"
width="476.65652"
height="212.95724"
id="rect1716" />
<clipPath
id="clip0">
<rect
width="770"
height="222.03999"
fill="#ffffff"
id="rect14"
x="0"
y="0" />
</clipPath>
</defs>
<text
xml:space="preserve"
id="text1714"
style="font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1716);"
transform="translate(44.332916,-25.667084)" />
<rect
style="fill:#ffffff;stroke:none;stroke-width:1.60003;stop-color:#000000"
id="rect1756"
width="240"
height="100"
x="0"
y="0" />
<rect
style="fill:#ffffff;stroke:none;stroke-width:1.52703;stop-color:#000000"
id="rect1758"
width="230"
height="90"
x="5"
y="5" />
<text
xml:space="preserve"
style="font-size:16px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;stroke-width:0.489974"
x="5.046875"
y="81.521378"
id="text1712"><tspan
id="tspan1710"
x="5.046875"
y="81.521378"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;font-family:Roboto;-inkscape-font-specification:Roboto;stroke-width:0.489974">Deploy your FastAPI app for free</tspan></text>
<g
clip-path="url(#clip0)"
id="g12"
transform="matrix(0.19133908,0,0,0.19133908,46.334454,11.992465)">
<path
d="m 111.14,0 c 61.38,0 111.139,49.7054 111.139,111.02 0,61.315 -49.759,111.02 -111.139,111.02 C 49.7589,222.04 0,172.335 0,111.02 0,49.7054 49.7589,0 111.14,0 Z"
fill="#ef39a8"
id="path2" />
<path
d="m 111.404,21.6757 c 49.689,0 89.97,40.2376 89.97,89.8733 0,49.636 -40.281,89.873 -89.97,89.873 -49.689,0 -89.9702,-40.237 -89.9702,-89.873 0,-49.6357 40.2812,-89.8733 89.9702,-89.8733 z"
fill="#bd399c"
id="path4" />
<path
d="m 111.404,45.4653 c 36.536,0 66.154,29.5861 66.154,66.0837 0,36.497 -29.618,66.083 -66.154,66.083 -36.536,0 -66.154,-29.586 -66.154,-66.083 0,-36.4976 29.618,-66.0837 66.154,-66.0837 z"
fill="#93388e"
id="path6" />
<path
d="m 110.874,65.5554 c 24.844,0 44.985,20.1184 44.985,44.9366 0,24.817 -20.141,44.936 -44.985,44.936 -24.8437,0 -44.9846,-20.119 -44.9846,-44.936 0,-24.8182 20.1409,-44.9366 44.9846,-44.9366 z"
fill="#6030a2"
id="path8" />
<path
d="m 339,170.836 h 49.915 c 23.004,0 40.365,-5.842 51.867,-17.745 11.719,-11.902 17.579,-25.752 17.579,-41.983 0,-16.2301 -5.86,-30.2964 -17.579,-42.1987 C 429.28,57.007 411.919,51.1641 388.915,51.1641 H 339 Z m 96.574,-59.728 c 0,11.686 -3.907,21.641 -11.719,29.864 -7.596,8.007 -19.315,12.119 -34.94,12.119 H 361.136 V 68.9093 h 27.779 c 15.625,0 27.344,4.1117 34.94,12.1186 7.812,8.2235 11.719,18.1781 11.719,30.0801 z m 40.582,10.388 c 0,30.08 19.098,51.504 52.302,51.504 22.136,0 39.931,-10.604 47.744,-30.513 h -24.523 c -5.426,8.44 -13.022,12.768 -23.221,12.768 -16.928,0 -27.778,-10.82 -29.732,-27.7 h 79.212 v -6.059 c 0,-29.6478 -19.966,-51.5047 -50.782,-51.5047 -31.034,0 -51,21.2077 -51,51.5047 z m 78.995,-8.224 h -56.208 c 2.388,-14.9316 11.936,-25.5355 28.213,-25.5355 15.843,0 25.608,10.3875 27.995,25.5355 z m 73.353,20.992 V 88.3857 h 24.957 V 72.1553 H 628.504 V 49 h -21.702 v 23.1553 h -16.06 v 16.2304 h 16.06 v 45.8783 c 0,14.499 3.038,24.237 9.332,29.431 6.293,5.193 15.191,7.79 26.693,7.79 3.69,0 6.944,-0.216 9.766,-0.865 l 4.123,-0.866 v -17.096 l -4.123,0.433 c -2.822,0.433 -6.076,0.649 -9.766,0.649 -11.719,0 -14.323,-6.059 -14.323,-19.476 z m 93.101,-63.6235 c -14.54,0 -25.825,3.0297 -33.638,9.3055 -8.029,6.2757 -11.936,13.8499 -11.936,22.723 h 22.136 c 0,-10.3879 11.719,-14.2833 23.438,-14.2833 14.757,0 23.872,5.1937 23.872,18.8273 v 6.059 h -26.693 c -26.259,0 -46.659,6.709 -46.659,28.782 0,20.342 15.625,30.946 38.847,30.946 14.973,0 25.607,-3.679 31.901,-11.037 l 3.039,-3.678 c 0,4.111 1.735,10.387 2.386,12.551 H 770 v -1.731 l -1.519,-4.761 c -0.868,-3.246 -1.302,-8.223 -1.302,-15.148 v -38.088 c 0,-28.998 -16.493,-40.4675 -45.574,-40.4675 z m 23.872,57.1305 c 0,19.693 -9.982,29.864 -28.863,29.864 -12.37,0 -22.354,-4.111 -22.354,-14.499 0,-11.902 10.852,-15.365 24.524,-15.581 z"
fill="#000000"
id="path10" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -0,0 +1,118 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
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 63.5 26.458334"
version="1.1"
id="svg975">
<defs
id="defs969">
<clipPath
id="clip0">
<rect
width="770"
height="222.03999"
fill="#ffffff"
id="rect14"
x="0"
y="0" />
</clipPath>
<clipPath
id="clip0-7">
<rect
width="770"
height="222.03999"
fill="#ffffff"
id="rect14-5"
x="0"
y="0" />
</clipPath>
</defs>
<metadata
id="metadata972">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
transform="translate(-75.455132,-135.96141)">
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.364576;stop-color:#000000"
id="rect901"
width="63.5"
height="26.458334"
x="75.455132"
y="135.96141" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.404023;stop-color:#000000"
id="rect1758"
width="60.854168"
height="23.8125"
x="76.778053"
y="137.28433" />
<text
xml:space="preserve"
style="font-size:4.23333px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;stroke-width:0.133861"
x="107.22684"
y="154.45795"
id="text1712"><tspan
x="107.22684"
y="154.45795"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333px;font-family:Roboto;-inkscape-font-specification:Roboto;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.133861"
id="tspan2004">We deal in big ideas. You in?</tspan><tspan
x="107.22684"
y="159.79095"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333px;font-family:Roboto;-inkscape-font-specification:Roboto;text-align:center;text-anchor:middle;fill:#000000;stroke-width:0.133861"
id="tspan874" /></text>
<g
id="g1003"
transform="matrix(0.02061785,0,0,0.02061785,70.802235,134.33866)">
<g
id="g1015"
transform="translate(4.0510205)">
<path
d="m 900.5,226.1 c -21.9,23 -28.6,35.3 -44.3,70.1 L 710.9,630 608.2,396.1 506.6,630 360.2,296.2 c -15.2,-34.8 -21.9,-46 -44.3,-70.1 h 185.7 c -14,11.8 -21.3,26.9 -21.3,46 0,13.4 2.3,23 9.5,40.4 l 55.5,132.4 41,-98.7 -23,-53.3 c -13.5,-30.8 -23,-49.9 -36.5,-66.7 h 185.7 c -18,11.8 -26.9,26.9 -26.9,46 0,13.4 2.3,23 9.5,40.4 L 751.8,445 807.9,312.6 c 7.3,-17.4 10.1,-26.9 10.1,-39.8 0,-16.8 -11.8,-37 -25.3,-46.5 z"
id="path966" />
<path
d="m 1093.5,523.4 c -18,78 -61.2,103.8 -124,103.8 -71.8,0 -139.2,-52.2 -139.2,-150.3 0,-94.2 59.5,-161 137.5,-161 51.1,0 122.9,26.4 122.9,137.4 H 921.3 c 11.8,59.4 50.5,90.3 104.4,90.3 27.4,0 46.5,-5 67.8,-20.2 z M 917.9,414.6 v 7.3 H 992 c 0,-56.1 -12.4,-73.5 -35.9,-73.5 -24.2,0 -38.2,24.1 -38.2,66.2 z"
id="path968" />
<path
d="M 1433.6,327.6 C 1387,283.3 1341,260.3 1305.7,260.3 v 247.4 c 0,49.9 12.9,80.2 47.1,111.1 h -212.1 c 34.2,-30.8 47.1,-61.1 47.1,-111.1 V 260.3 c -35.4,0 -83.6,23 -127.9,67.3 l 22.5,-118.4 c 15.2,11.8 43.2,16.8 74.6,16.8 h 179.6 c 31.4,0 59.5,-5.1 74.6,-16.8 z"
id="path970" />
<path
d="m 1562.6,618.8 h -178.4 c 21.9,-25.8 31.4,-42.6 31.4,-83.6 v -90.9 c 0,-32 -4.5,-47.1 -25.8,-66.7 l -12.3,-11.2 134.7,-50.5 V 386 c 12.9,-40.4 33.1,-70.1 66.2,-70.1 26.9,0 44.3,19.1 44.3,47.1 0,29.7 -18.5,50.5 -44.3,50.5 -5.6,-12.9 -19.1,-19.1 -31.4,-19.1 -10.1,0 -19.6,2.8 -24.7,7.9 v 129.6 c -0.1,43.1 7.2,54.9 40.3,86.9 z"
id="path972" />
<path
d="m 1931.3,567.2 c -6.7,35.3 -35.9,60 -75.8,60 -33.7,0 -59.5,-20.2 -67.3,-43.2 -16.8,30.3 -48.3,43.2 -81.9,43.2 -46.6,0 -78,-30.8 -78,-72.9 0,-49.4 35.4,-83.6 116.7,-103.2 l 37.6,-9 v -50.5 c 0,-31.4 -10.7,-44.3 -29.7,-44.3 -17.9,0 -29.7,11.8 -29.7,28 0,14 6.7,23 18.5,34.2 0,17.9 -28.1,36.4 -57.2,36.4 -28.6,0 -48.8,-21.9 -48.8,-48.8 0,-47.7 52.7,-81.3 130.2,-81.3 80.8,0 123.4,34.2 123.4,110.5 v 120.6 c 0,15.1 9,25.2 23,25.2 8.3,0.1 14.5,-1.6 19,-4.9 z m -148.7,-8.4 v -90.3 l -7.3,2.2 c -24.1,7.3 -40.4,23 -40.4,54.4 0,26.9 10.7,43.2 28.1,43.2 8.9,0 16.2,-2.8 19.6,-9.5 z"
id="path974" />
<path
d="m 2083.3,618.8 h -150.9 c 15.7,-15.1 25.8,-37.6 25.8,-83.6 v -90.9 c 0,-30.8 -3.9,-46.5 -22.4,-63.9 l -12.9,-11.8 139.2,-52.7 v 43.7 c 16.3,-26.9 50.5,-43.7 84.7,-43.7 53.9,0 83.6,29.2 83.6,81.3 v 157.1 c 0,32 8.4,51.6 21.9,64.5 h -147 c 14.6,-14 18.5,-33.1 18.5,-48.2 V 410.1 c 0,-23.5 -7.8,-35.3 -29.7,-35.3 -12.3,0 -22.5,4.5 -29.2,11.2 v 184.5 c -0.1,15.2 3.8,33.7 18.4,48.3 z"
id="path976" />
<path
d="m 2279.7,602.5 v -95.9 c 40.4,52.7 82.5,81.9 121.8,81.9 19.1,0 28.1,-10.1 28.1,-24.1 0,-13.5 -7.3,-21.3 -20.2,-26.4 l -65.1,-24.1 c -49.9,-18.5 -72.4,-49.4 -72.4,-95.3 0,-59.4 48.8,-102.6 118.4,-102.6 37.6,0 79.1,10.6 99.9,25.8 v 81.9 c -25.8,-45.4 -67.9,-70.7 -108.9,-70.7 -20.8,0 -31.4,6.7 -31.4,19.6 0,12.9 7.9,17.9 25.2,25.2 l 76.9,31.4 c 38.7,15.7 56.1,48.8 56.1,88.6 0,65.6 -47.7,109.4 -119.5,109.4 -36,0 -73,-7.9 -108.9,-24.7 z"
id="path978" />
<path
d="m 2519.3,352.3 32.5,-49.9 c 41.5,-62.8 74.7,-93.1 130.8,-93.1 43.8,0 71.8,19.1 71.8,47.7 0,24.7 -20.2,42.6 -62.9,42.6 0,-34.8 -19.6,-47.7 -39.3,-47.7 -19.6,0 -34.8,14 -34.8,37 0,15.7 8.4,31.4 34.2,35.3 h 62.3 l -22.5,28 h -38.2 v 166.6 c 0,31.4 5.1,59.4 37.6,88.1 l 13.5,11.8 h -193.6 c 22.5,-22.4 35.9,-49.9 35.9,-90.3 V 352.3 Z"
id="path980" />
<path
d="m 2959.2,523.4 c -18,78 -61.2,103.8 -124,103.8 -71.8,0 -139.2,-52.2 -139.2,-150.3 0,-94.2 59.5,-161 137.5,-161 51.1,0 122.9,26.4 122.9,137.4 H 2787 c 11.8,59.4 50.5,90.3 104.4,90.3 27.4,0 46.5,-5 67.8,-20.2 z M 2783.6,414.6 v 7.3 h 74.1 c 0,-56.1 -12.4,-73.5 -35.9,-73.5 -24.2,0 -38.2,24.1 -38.2,66.2 z"
id="path982" />
<path
d="m 3147.2,618.8 h -178.4 c 21.9,-25.8 31.4,-42.6 31.4,-83.6 v -90.9 c 0,-32 -4.5,-47.1 -25.8,-66.7 L 2962,366.4 3096.7,315.9 V 386 c 12.9,-40.4 33.1,-70.1 66.2,-70.1 26.9,0 44.3,19.1 44.3,47.1 0,29.7 -18.5,50.5 -44.3,50.5 -5.6,-12.9 -19.1,-19.1 -31.4,-19.1 -10.1,0 -19.6,2.8 -24.7,7.9 v 129.6 c 0,43.1 7.3,54.9 40.4,86.9 z"
id="path984" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 73 KiB

View File

@@ -0,0 +1,43 @@
<mxfile host="65bd71144e" modified="2020-11-28T18:13:19.199Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Code/1.51.1 Chrome/83.0.4103.122 Electron/9.3.3 Safari/537.36" etag="KPHuXUeExV3PdWouu_3U" version="13.6.5">
<diagram id="zB4-QXJZ7ScUzHSLnJ1i" name="Page-1">
<mxGraphModel dx="1154" dy="780" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1920" pageHeight="1200" math="0" shadow="0" extFonts="Roboto^https://fonts.googleapis.com/css?family=Roboto|Roboto Mono, mono^https://fonts.googleapis.com/css?family=Roboto+Mono%2C+mono">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;" parent="1" vertex="1">
<mxGeometry x="110" y="280" width="1350" height="620" as="geometry"/>
</mxCell>
<mxCell id="3" value="&lt;font style=&quot;font-size: 24px&quot; face=&quot;Roboto&quot;&gt;Package app&lt;br&gt;app/__init__.py&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1">
<mxGeometry x="635" y="310" width="300" height="80" as="geometry"/>
</mxCell>
<mxCell id="15" value="&lt;span style=&quot;font-family: &amp;#34;roboto&amp;#34; ; font-size: 24px&quot;&gt;Module app.main&lt;/span&gt;&lt;br style=&quot;font-family: &amp;#34;roboto&amp;#34; ; font-size: 24px&quot;&gt;&lt;span style=&quot;font-family: &amp;#34;roboto&amp;#34; ; font-size: 24px&quot;&gt;app/main.py&lt;/span&gt;" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1">
<mxGeometry x="140" y="430" width="360" height="100" as="geometry"/>
</mxCell>
<mxCell id="16" value="&lt;span style=&quot;font-family: &amp;#34;roboto&amp;#34; ; font-size: 24px&quot;&gt;Module app.dependencies&lt;/span&gt;&lt;br style=&quot;font-family: &amp;#34;roboto&amp;#34; ; font-size: 24px&quot;&gt;&lt;span style=&quot;font-family: &amp;#34;roboto&amp;#34; ; font-size: 24px&quot;&gt;app/dependencies.py&lt;/span&gt;" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1">
<mxGeometry x="130" y="565" width="370" height="100" as="geometry"/>
</mxCell>
<mxCell id="5" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;" parent="1" vertex="1">
<mxGeometry x="1030" y="430" width="400" height="260" as="geometry"/>
</mxCell>
<mxCell id="8" value="&lt;font style=&quot;font-size: 24px&quot; face=&quot;Roboto&quot;&gt;Subpackage app.internal&lt;br&gt;&lt;/font&gt;&lt;span style=&quot;font-family: &amp;#34;roboto&amp;#34; ; font-size: 24px&quot;&gt;app/internal/__init__.py&lt;/span&gt;&lt;font style=&quot;font-size: 24px&quot; face=&quot;Roboto&quot;&gt;&lt;br&gt;&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1">
<mxGeometry x="1083.8438461538462" y="460" width="292.3076923076923" height="80" as="geometry"/>
</mxCell>
<mxCell id="19" value="&lt;span style=&quot;font-family: &amp;#34;roboto&amp;#34; ; font-size: 24px&quot;&gt;Module app.internal.admin&lt;/span&gt;&lt;br style=&quot;font-family: &amp;#34;roboto&amp;#34; ; font-size: 24px&quot;&gt;&lt;span style=&quot;font-family: &amp;#34;roboto&amp;#34; ; font-size: 24px&quot;&gt;app/internal/admin.py&lt;/span&gt;" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1">
<mxGeometry x="1050" y="570" width="360" height="100" as="geometry"/>
</mxCell>
<mxCell id="4" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;" parent="1" vertex="1">
<mxGeometry x="540" y="430" width="440" height="410" as="geometry"/>
</mxCell>
<mxCell id="7" value="&lt;font style=&quot;font-size: 24px&quot; face=&quot;Roboto&quot;&gt;Subpackage app.routers&lt;br&gt;app/routers/__init__.py&lt;br&gt;&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1">
<mxGeometry x="599.2307692307693" y="460" width="321.53846153846155" height="80" as="geometry"/>
</mxCell>
<mxCell id="17" value="&lt;span style=&quot;font-family: &amp;#34;roboto&amp;#34; ; font-size: 24px&quot;&gt;Module app.routers.items&lt;/span&gt;&lt;br style=&quot;font-family: &amp;#34;roboto&amp;#34; ; font-size: 24px&quot;&gt;&lt;span style=&quot;font-family: &amp;#34;roboto&amp;#34; ; font-size: 24px&quot;&gt;app/routers/items.py&lt;/span&gt;" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1">
<mxGeometry x="580" y="570" width="360" height="100" as="geometry"/>
</mxCell>
<mxCell id="18" value="&lt;span style=&quot;font-family: &amp;#34;roboto&amp;#34; ; font-size: 24px&quot;&gt;Module app.routers.users&lt;/span&gt;&lt;br style=&quot;font-family: &amp;#34;roboto&amp;#34; ; font-size: 24px&quot;&gt;&lt;span style=&quot;font-family: &amp;#34;roboto&amp;#34; ; font-size: 24px&quot;&gt;app/routers/users.py&lt;/span&gt;" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1">
<mxGeometry x="580" y="700" width="360" height="100" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View File

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 116 KiB

View File

@@ -14,9 +14,6 @@
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Package version">
</a>
<a href="https://gitter.im/tiangolo/fastapi?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge" target="_blank">
<img src="https://badges.gitter.im/tiangolo/fastapi.svg" alt="Join the chat at https://gitter.im/tiangolo/fastapi">
</a>
</p>
---
@@ -39,10 +36,24 @@ The key features are:
* **Easy**: Designed to be easy to use and learn. Less time reading docs.
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
* **Robust**: Get production-ready code. With automatic interactive documentation.
* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (previously known as Swagger) and <a href="http://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (previously known as Swagger) and <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
<small>* estimation based on tests on an internal development team, building production applications.</small>
## Gold Sponsors
<!-- sponsors -->
{% if sponsors %}
{% for sponsor in sponsors.gold -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}"></a>
{% endfor %}
{% endif %}
<!-- /sponsors -->
<a href="https://fastapi.tiangolo.com/fastapi-people/#sponsors" class="external-link" target="_blank">Other sponsors</a>
## Opinions
"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._"
@@ -71,7 +82,7 @@ The key features are:
"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._"
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="http://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
---
@@ -112,7 +123,7 @@ $ pip install fastapi
</div>
You will also need an ASGI server, for production such as <a href="http://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> or <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>.
You will also need an ASGI server, for production such as <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> or <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>.
<div class="termy">
@@ -153,7 +164,7 @@ def read_item(item_id: int, q: Optional[str] = None):
If your code uses `async` / `await`, use `async def`:
```Python hl_lines="9 14"
```Python hl_lines="9 14"
from typing import Optional
from fastapi import FastAPI
@@ -245,7 +256,7 @@ Now modify the file `main.py` to receive a body from a `PUT` request.
Declare the body using standard Python types, thanks to Pydantic.
```Python hl_lines="4 9 10 11 12 25 26 27"
```Python hl_lines="4 9-12 25-27"
from typing import Optional
from fastapi import FastAPI
@@ -428,9 +439,9 @@ Used by Pydantic:
Used by Starlette:
* <a href="http://docs.python-requests.org" target="_blank"><code>requests</code></a> - Required if you want to use the `TestClient`.
* <a href="https://requests.readthedocs.io" target="_blank"><code>requests</code></a> - Required if you want to use the `TestClient`.
* <a href="https://github.com/Tinche/aiofiles" target="_blank"><code>aiofiles</code></a> - Required if you want to use `FileResponse` or `StaticFiles`.
* <a href="http://jinja.pocoo.org" target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`.
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Required for `SessionMiddleware` support.
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Required for Starlette's `SchemaGenerator` support (you probably don't need it with FastAPI).
@@ -439,7 +450,7 @@ Used by Starlette:
Used by FastAPI / Starlette:
* <a href="http://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - for the server that loads and serves your application.
* <a href="https://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - for the server that loads and serves your application.
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - Required if you want to use `ORJSONResponse`.
You can install all of these with `pip install fastapi[all]`.

View File

@@ -20,7 +20,7 @@ GitHub: <a href="https://github.com/tiangolo/full-stack-fastapi-postgresql" clas
* **Easy**: Designed to be easy to use and learn. Less time reading docs.
* **Short**: Minimize code duplication. Multiple features from each parameter declaration.
* **Robust**: Get production-ready code. With automatic interactive documentation.
* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> and <a href="http://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> and <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
* <a href="https://fastapi.tiangolo.com/features/" class="external-link" target="_blank">**Many other features**</a> including automatic validation, serialization, interactive documentation, authentication with OAuth2 JWT tokens, etc.
* **Secure password** hashing by default.
* **JWT token** authentication.

View File

@@ -1,8 +1,8 @@
# Python Types Intro
**Python 3.6+** has support for optional "type hints".
Python has support for optional "type hints".
These **"type hints"** are a new syntax (since Python 3.6+) that allow declaring the <abbr title="for example: str, int, float, bool">type</abbr> of a variable.
These **"type hints"** are a special syntax that allow declaring the <abbr title="for example: str, int, float, bool">type</abbr> of a variable.
By declaring types for your variables, editors and tools can give you better support.
@@ -193,7 +193,7 @@ And still, the editor knows it is a `str`, and provides support for that.
You would do the same to declare `tuple`s and `set`s:
```Python hl_lines="1 4"
```Python hl_lines="1 4"
{!../../../docs_src/python_types/tutorial007.py!}
```
@@ -210,7 +210,7 @@ The first type parameter is for the keys of the `dict`.
The second type parameter is for the values of the `dict`:
```Python hl_lines="1 4"
```Python hl_lines="1 4"
{!../../../docs_src/python_types/tutorial008.py!}
```
@@ -224,7 +224,7 @@ This means:
You can also use `Optional` to declare that a variable has a type, like `str`, but that it is "optional", which means that it could also be `None`:
```Python hl_lines="1 4"
```Python hl_lines="1 4"
{!../../../docs_src/python_types/tutorial009.py!}
```
@@ -249,7 +249,7 @@ You can also declare a class as the type of a variable.
Let's say you have a class `Person`, with a name:
```Python hl_lines="1 2 3"
```Python hl_lines="1-3"
{!../../../docs_src/python_types/tutorial010.py!}
```

View File

@@ -1,6 +1,257 @@
# Release Notes
## Latest changes
## Latest Changes
## 0.62.0
### Features
* ✨ Add support for shared/top-level parameters (dependencies, tags, etc). PR [#2434](https://github.com/tiangolo/fastapi/pull/2434) by [@tiangolo](https://github.com/tiangolo).
Up to now, for several options, the only way to apply them to a group of *path operations* was in `include_router`. That works well, but the call to `app.include_router()` or `router.include_router()` is normally done in another file.
That means that, for example, to apply authentication to all the *path operations* in a router it would end up being done in a different file, instead of keeping related logic together.
Setting options in `include_router` still makes sense in some cases, for example, to override or increase configurations from a third party router included in an app. But in a router that is part of a bigger application, it would probably make more sense to add those settings when creating the `APIRouter`.
**In `FastAPI`**
This allows setting the (mostly new) parameters (additionally to the already existing parameters):
* `default_response_class`: updated to handle defaults in `APIRouter` and `include_router`.
* `dependencies`: to include ✨ top-level dependencies ✨ that apply to the whole application. E.g. to add global authentication.
* `callbacks`: OpenAPI callbacks that apply to all the *path operations*.
* `deprecated`: to mark all the *path operations* as deprecated. 🤷
* `include_in_schema`: to allow excluding all the *path operations* from the OpenAPI schema.
* `responses`: OpenAPI responses that apply to all the *path operations*.
For example:
```Python
from fastapi import FastAPI, Depends
async def some_dependency():
return
app = FastAPI(dependencies=[Depends(some_dependency)])
```
**In `APIRouter`**
This allows setting the (mostly new) parameters (additionally to the already existing parameters):
* `default_response_class`: updated to handle defaults in `APIRouter` and `include_router`. For example, it's not needed to set it explicitly when [creating callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
* `dependencies`: to include ✨ router-level dependencies ✨ that apply to all the *path operations* in a router. Up to now, this was only possible with `include_router`.
* `callbacks`: OpenAPI callbacks that apply to all the *path operations* in this router.
* `deprecated`: to mark all the *path operations* in a router as deprecated.
* `include_in_schema`: to allow excluding all the *path operations* in a router from the OpenAPI schema.
* `responses`: OpenAPI responses that apply to all the *path operations* in a router.
* `prefix`: to set the path prefix for a router. Up to now, this was only possible when calling `include_router`.
* `tags`: OpenAPI tags to apply to all the *path operations* in this router.
For example:
```Python
from fastapi import APIRouter, Depends
async def some_dependency():
return
router = APIRouter(prefix="/users", dependencies=[Depends(some_dependency)])
```
**In `include_router`**
Most of these settings are now supported in `APIRouter`, which normally lives closer to the related code, so it is recommended to use `APIRouter` when possible.
But `include_router` is still useful to, for example, adding options (like `dependencies`, `prefix`, and `tags`) when including a third party router, or a generic router that is shared between several projects.
This PR allows setting the (mostly new) parameters (additionally to the already existing parameters):
* `default_response_class`: updated to handle defaults in `APIRouter` and `FastAPI`.
* `deprecated`: to mark all the *path operations* in a router as deprecated in OpenAPI.
* `include_in_schema`: to allow disabling all the *path operations* from showing in the OpenAPI schema.
* `callbacks`: OpenAPI callbacks that apply to all the *path operations* in this router.
Note: all the previous parameters are still there, so it's still possible to declare `dependencies` in `include_router`.
### Breaking Changes
* PR [#2434](https://github.com/tiangolo/fastapi/pull/2434) includes several improvements that shouldn't affect normal use cases, but could affect in advanced scenarios:
* If you are testing the generated OpenAPI (you shouldn't, FastAPI already tests it extensively for you): the order for `tags` in `include_router` and *path operations* was updated for consistency, but it's a simple order change.
* If you have advanced custom logic to access each route's `route.response_class`, or the `router.default_response_class`, or the `app.default_response_class`: the default value for `response_class` in `APIRoute` and for `default_response_class` in `APIRouter` and `FastAPI` is now a `DefaultPlaceholder` used internally to handle and solve default values and overrides. The actual response class inside the `DefaultPlaceholder` is available at `route.response_class.value`.
### Docs
* PR [#2434](https://github.com/tiangolo/fastapi/pull/2434) (above) includes new or updated docs:
* <a href="https://fastapi.tiangolo.com/advanced/openapi-callbacks/" class="external-link" target="_blank">Advanced User Guide - OpenAPI Callbacks</a>.
* <a href="https://fastapi.tiangolo.com/tutorial/bigger-applications/" class="external-link" target="_blank">Tutorial - Bigger Applications</a>.
* <a href="https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/" class="external-link" target="_blank">Tutorial - Dependencies - Dependencies in path operation decorators</a>.
* <a href="https://fastapi.tiangolo.com/tutorial/dependencies/global-dependencies/" class="external-link" target="_blank">Tutorial - Dependencies - Global Dependencies</a>.
* 📝 Add FastAPI monitoring blog post to External Links. PR [#2324](https://github.com/tiangolo/fastapi/pull/2324) by [@louisguitton](https://github.com/louisguitton).
* ✏️ Fix typo in Deta tutorial. PR [#2320](https://github.com/tiangolo/fastapi/pull/2320) by [@tiangolo](https://github.com/tiangolo).
* ✨ Add Discord chat. PR [#2322](https://github.com/tiangolo/fastapi/pull/2322) by [@tiangolo](https://github.com/tiangolo).
* 📝 Fix image links for sponsors. PR [#2304](https://github.com/tiangolo/fastapi/pull/2304) by [@tiangolo](https://github.com/tiangolo).
### Translations
* 🌐 Add Japanese translation for Advanced - Custom Response. PR [#2193](https://github.com/tiangolo/fastapi/pull/2193) by [@Attsun1031](https://github.com/Attsun1031).
* 🌐 Add Chinese translation for Benchmarks. PR [#2119](https://github.com/tiangolo/fastapi/pull/2119) by [@spaceack](https://github.com/spaceack).
* 🌐 Add Chinese translation for Tutorial - Body - Nested Models. PR [#1609](https://github.com/tiangolo/fastapi/pull/1609) by [@waynerv](https://github.com/waynerv).
* 🌐 Add Chinese translation for Advanced - Custom Response. PR [#1459](https://github.com/tiangolo/fastapi/pull/1459) by [@RunningIkkyu](https://github.com/RunningIkkyu).
* 🌐 Add Chinese translation for Advanced - Return a Response Directly. PR [#1452](https://github.com/tiangolo/fastapi/pull/1452) by [@RunningIkkyu](https://github.com/RunningIkkyu).
* 🌐 Add Chinese translation for Advanced - Additional Status Codes. PR [#1451](https://github.com/tiangolo/fastapi/pull/1451) by [@RunningIkkyu](https://github.com/RunningIkkyu).
* 🌐 Add Chinese translation for Advanced - Path Operation Advanced Configuration. PR [#1447](https://github.com/tiangolo/fastapi/pull/1447) by [@RunningIkkyu](https://github.com/RunningIkkyu).
* 🌐 Add Chinese translation for Advanced User Guide - Intro. PR [#1445](https://github.com/tiangolo/fastapi/pull/1445) by [@RunningIkkyu](https://github.com/RunningIkkyu).
### Internal
* 🔧 Update TestDriven link to course in sponsors section. PR [#2435](https://github.com/tiangolo/fastapi/pull/2435) by [@tiangolo](https://github.com/tiangolo).
* 🍱 Update sponsor logos. PR [#2418](https://github.com/tiangolo/fastapi/pull/2418) by [@tiangolo](https://github.com/tiangolo).
* 💚 Fix disabling install of Material for MkDocs Insiders in forks, strike 1 ⚾. PR [#2340](https://github.com/tiangolo/fastapi/pull/2340) by [@tiangolo](https://github.com/tiangolo).
* 🐛 Fix disabling Material for MkDocs Insiders install in forks. PR [#2339](https://github.com/tiangolo/fastapi/pull/2339) by [@tiangolo](https://github.com/tiangolo).
* ✨ Add silver sponsor WeTransfer. PR [#2338](https://github.com/tiangolo/fastapi/pull/2338) by [@tiangolo](https://github.com/tiangolo).
* ✨ Set up and enable Material for MkDocs Insiders for the docs. PR [#2325](https://github.com/tiangolo/fastapi/pull/2325) by [@tiangolo](https://github.com/tiangolo).
## 0.61.2
### Fixes
* 📌 Relax Swagger UI version pin. PR [#2089](https://github.com/tiangolo/fastapi/pull/2089) by [@jmriebold](https://github.com/jmriebold).
* 🐛 Fix bug overriding custom HTTPException and RequestValidationError from exception_handlers. PR [#1924](https://github.com/tiangolo/fastapi/pull/1924) by [@uriyyo](https://github.com/uriyyo).
* ✏️ Fix typo on dependencies utils and cleanup unused variable. PR [#1912](https://github.com/tiangolo/fastapi/pull/1912) by [@Kludex](https://github.com/Kludex).
### Docs
* ✏️ Fix typo in Tutorial - Path Parameters. PR [#2231](https://github.com/tiangolo/fastapi/pull/2231) by [@mariacamilagl](https://github.com/mariacamilagl).
* ✏ Fix a stylistic error in docs. PR [#2206](https://github.com/tiangolo/fastapi/pull/2206) by [@ddobrinskiy](https://github.com/ddobrinskiy).
* ✏ Fix capitalizaiton typo in docs. PR [#2204](https://github.com/tiangolo/fastapi/pull/2204) by [@imba-tjd](https://github.com/imba-tjd).
* ✏ Fix typo in docs. PR [#2179](https://github.com/tiangolo/fastapi/pull/2179) by [@ammarasmro](https://github.com/ammarasmro).
* 📝 Update/fix links in docs to use HTTPS. PR [#2165](https://github.com/tiangolo/fastapi/pull/2165) by [@imba-tjd](https://github.com/imba-tjd).
* ✏ Fix typos and add rewording in docs. PR [#2159](https://github.com/tiangolo/fastapi/pull/2159) by [@nukopy](https://github.com/nukopy).
* 📝 Fix code consistency in examples for Tutorial - User Guide - Path Parameters. PR [#2158](https://github.com/tiangolo/fastapi/pull/2158) by [@nukopy](https://github.com/nukopy).
* 📝 Fix renamed parameter `content_type` typo. PR [#2135](https://github.com/tiangolo/fastapi/pull/2135) by [@TeoZosa](https://github.com/TeoZosa).
* ✏ Fix minor typos in docs. PR [#2122](https://github.com/tiangolo/fastapi/pull/2122) by [@TeoZosa](https://github.com/TeoZosa).
* ✏ Fix typos in docs and source examples. PR [#2102](https://github.com/tiangolo/fastapi/pull/2102) by [@AdrianDeAnda](https://github.com/AdrianDeAnda).
* ✏ Fix incorrect Celery URLs in docs. PR [#2100](https://github.com/tiangolo/fastapi/pull/2100) by [@CircleOnCircles](https://github.com/CircleOnCircles).
* 📝 Simplify intro to Python Types, all currently supported Python versions include type hints 🎉. PR [#2085](https://github.com/tiangolo/fastapi/pull/2085) by [@ninjaaron](https://github.com/ninjaaron).
* 📝 Fix example code with sets in Tutorial - Body - Nested Models 3. PR [#2054](https://github.com/tiangolo/fastapi/pull/2054) by [@hitrust](https://github.com/hitrust).
* 📝 Fix example code with sets in Tutorial - Body - Nested Models 2. PR [#2053](https://github.com/tiangolo/fastapi/pull/2053) by [@hitrust](https://github.com/hitrust).
* 📝 Fix example code with sets in Tutorial - Body - Nested Models. PR [#2052](https://github.com/tiangolo/fastapi/pull/2052) by [@hitrust](https://github.com/hitrust).
* ✏ Fix typo in Benchmarks. PR [#1995](https://github.com/tiangolo/fastapi/pull/1995) by [@AlejoAsd](https://github.com/AlejoAsd).
* 📝 Add note in CORS tutorial about allow_origins with ["*"] and allow_credentials. PR [#1895](https://github.com/tiangolo/fastapi/pull/1895) by [@dsmurrell](https://github.com/dsmurrell).
* 📝 Add deployment to Deta, the first gold sponsor 🎉. PR [#2303](https://github.com/tiangolo/fastapi/pull/2303) by [@tiangolo](https://github.com/tiangolo).
* 👥 Update FastAPI People. PR [#2282](https://github.com/tiangolo/fastapi/pull/2282) by [@github-actions[bot]](https://github.com/apps/github-actions).
* ✏️ Fix uppercase in Tutorial - Query parameters. PR [#2245](https://github.com/tiangolo/fastapi/pull/2245) by [@mariacamilagl](https://github.com/mariacamilagl).
* 📝 Add articles to External Links. PR [#2247](https://github.com/tiangolo/fastapi/pull/2247) by [@tiangolo](https://github.com/tiangolo).
* ✏ Fix typo in Spanish tutorial index. PR [#2020](https://github.com/tiangolo/fastapi/pull/2020) by [@aviloncho](https://github.com/aviloncho).
### Translations
* 🌐 Add Japanese translation for Advanced Tutorial - Response Directly. PR [#2191](https://github.com/tiangolo/fastapi/pull/2191) by [@Attsun1031](https://github.com/Attsun1031).
* 📝 Add Japanese translation for Tutorial - Security - First Steps. PR [#2153](https://github.com/tiangolo/fastapi/pull/2153) by [@komtaki](https://github.com/komtaki).
* 🌐 Add Japanese translation for Tutorial - Query Parameters and String Validations. PR [#1901](https://github.com/tiangolo/fastapi/pull/1901) by [@SwftAlpc](https://github.com/SwftAlpc).
* 🌐 Add Portuguese translation for External Links. PR [#1443](https://github.com/tiangolo/fastapi/pull/1443) by [@Serrones](https://github.com/Serrones).
* 🌐 Add Japanese translation for Tutorial - CORS. PR [#2125](https://github.com/tiangolo/fastapi/pull/2125) by [@tokusumi](https://github.com/tokusumi).
* 🌐 Add Japanese translation for Contributing. PR [#2067](https://github.com/tiangolo/fastapi/pull/2067) by [@komtaki](https://github.com/komtaki).
* 🌐 Add Japanese translation for Project Generation. PR [#2050](https://github.com/tiangolo/fastapi/pull/2050) by [@tokusumi](https://github.com/tokusumi).
* 🌐 Add Japanese translation for Alternatives. PR [#2043](https://github.com/tiangolo/fastapi/pull/2043) by [@Attsun1031](https://github.com/Attsun1031).
* 🌐 Add Japanese translation for History Design and Future. PR [#2002](https://github.com/tiangolo/fastapi/pull/2002) by [@komtaki](https://github.com/komtaki).
* 🌐 Add Japanese translation for Benchmarks. PR [#1992](https://github.com/tiangolo/fastapi/pull/1992) by [@komtaki](https://github.com/komtaki).
* 🌐 Add Japanese translation for Tutorial - Header Parameters. PR [#1935](https://github.com/tiangolo/fastapi/pull/1935) by [@SwftAlpc](https://github.com/SwftAlpc).
* 🌐 Add Portuguese translation for Tutorial - First Steps. PR [#1861](https://github.com/tiangolo/fastapi/pull/1861) by [@jessicapaz](https://github.com/jessicapaz).
* 🌐 Add Portuguese translation for Python Types. PR [#1796](https://github.com/tiangolo/fastapi/pull/1796) by [@izaguerreiro](https://github.com/izaguerreiro).
* 🌐 Add Japanese translation for Help FastAPI. PR [#1692](https://github.com/tiangolo/fastapi/pull/1692) by [@tokusumi](https://github.com/tokusumi).
* 🌐 Add Japanese translation for Tutorial - Body. PR [#1683](https://github.com/tiangolo/fastapi/pull/1683) by [@tokusumi](https://github.com/tokusumi).
* 🌐 Add Japanese translation for Tutorial - Query Params. PR [#1674](https://github.com/tiangolo/fastapi/pull/1674) by [@tokusumi](https://github.com/tokusumi).
* 🌐 Add Japanese translation for tutorial/path-params.md. PR [#1671](https://github.com/tiangolo/fastapi/pull/1671) by [@tokusumi](https://github.com/tokusumi).
* 🌐 Add Japanese translation for tutorial/first-steps.md. PR [#1658](https://github.com/tiangolo/fastapi/pull/1658) by [@tokusumi](https://github.com/tokusumi).
* 🌐 Add Japanese translation for tutorial/index.md. PR [#1656](https://github.com/tiangolo/fastapi/pull/1656) by [@tokusumi](https://github.com/tokusumi).
* 🌐 Add translation to Portuguese for Project Generation. PR [#1602](https://github.com/tiangolo/fastapi/pull/1602) by [@Serrones](https://github.com/Serrones).
* 🌐 Add Japanese translation for Features. PR [#1625](https://github.com/tiangolo/fastapi/pull/1625) by [@tokusumi](https://github.com/tokusumi).
* 🌐 Initialize new language Korean for translations. PR [#2018](https://github.com/tiangolo/fastapi/pull/2018) by [@hard-coders](https://github.com/hard-coders).
* 🌐 Add Portuguese translation of Deployment. PR [#1374](https://github.com/tiangolo/fastapi/pull/1374) by [@Serrones](https://github.com/Serrones).
### Internal
* 🔥 Cleanup after upgrade for Docs Previews GitHub Action. PR [#2248](https://github.com/tiangolo/fastapi/pull/2248) by [@tiangolo](https://github.com/tiangolo).
* 🐛 Fix CI docs preview, unzip docs. PR [#2246](https://github.com/tiangolo/fastapi/pull/2246) by [@tiangolo](https://github.com/tiangolo).
* ✨ Add instant docs deploy previews for PRs from forks. PR [#2244](https://github.com/tiangolo/fastapi/pull/2244) by [@tiangolo](https://github.com/tiangolo).
* ⚡️ Build docs for languages in parallel in subprocesses to speed up CI. PR [#2242](https://github.com/tiangolo/fastapi/pull/2242) by [@tiangolo](https://github.com/tiangolo).
* 🐛 Fix docs order generation for partial translations. PR [#2238](https://github.com/tiangolo/fastapi/pull/2238) by [@tiangolo](https://github.com/tiangolo).
* 👥 Update FastAPI People. PR [#2202](https://github.com/tiangolo/fastapi/pull/2202) by [@github-actions[bot]](https://github.com/apps/github-actions).
* ♻️ Update FastAPI People GitHub Action to send the PR as github-actions. PR [#2201](https://github.com/tiangolo/fastapi/pull/2201) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Update FastAPI People GitHub Action config, run monthly. PR [#2199](https://github.com/tiangolo/fastapi/pull/2199) by [@tiangolo](https://github.com/tiangolo).
* 🐛 Fix FastAPI People GitHub Action Docker dependency, strike 1 ⚾. PR [#2198](https://github.com/tiangolo/fastapi/pull/2198) by [@tiangolo](https://github.com/tiangolo).
* 🐛 Fix FastAPI People GitHub Action Docker dependencies. PR [#2197](https://github.com/tiangolo/fastapi/pull/2197) by [@tiangolo](https://github.com/tiangolo).
* 🐛 Fix FastAPI People GitHub Action when there's nothing to change. PR [#2196](https://github.com/tiangolo/fastapi/pull/2196) by [@tiangolo](https://github.com/tiangolo).
* 👥 Add new section FastAPI People. PR [#2195](https://github.com/tiangolo/fastapi/pull/2195) by [@tiangolo](https://github.com/tiangolo).
* ⬆️ Upgrade GitHub Action Latest Changes. PR [#2190](https://github.com/tiangolo/fastapi/pull/2190) by [@tiangolo](https://github.com/tiangolo).
* ⬆️ Upgrade GitHub Action Label Approved. PR [#2189](https://github.com/tiangolo/fastapi/pull/2189) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Update GitHub Action Label Approved, run at 12:00. PR [#2185](https://github.com/tiangolo/fastapi/pull/2185) by [@tiangolo](https://github.com/tiangolo).
* 👷 Upgrade GitHub Action Latest Changes. PR [#2184](https://github.com/tiangolo/fastapi/pull/2184) by [@tiangolo](https://github.com/tiangolo).
* 👷 Set GitHub Action Label Approved to run daily, not every minute. PR [#2163](https://github.com/tiangolo/fastapi/pull/2163) by [@tiangolo](https://github.com/tiangolo).
* 🔥 Remove pr-approvals GitHub Action as it's not compatible with forks. Use the new one. PR [#2162](https://github.com/tiangolo/fastapi/pull/2162) by [@tiangolo](https://github.com/tiangolo).
* 👷 Add GitHub Action Latest Changes. PR [#2160](https://github.com/tiangolo/fastapi/pull/2160).
* 👷 Add GitHub Action Label Approved. PR [#2161](https://github.com/tiangolo/fastapi/pull/2161).
## 0.61.1
### Fixes
* Fix issues using `jsonable_encoder` with SQLAlchemy models directly. PR [#1987](https://github.com/tiangolo/fastapi/pull/1987).
### Docs
* Fix typo in NoSQL docs. PR [#1980](https://github.com/tiangolo/fastapi/pull/1980) by [@facundojmaero](https://github.com/facundojmaero).
### Translations
* Add translation for [main page to Japanese](https://fastapi.tiangolo.com/ja/) PR [#1571](https://github.com/tiangolo/fastapi/pull/1571) by [@ryuckel](https://github.com/ryuckel).
* Initialize French translations. PR [#1975](https://github.com/tiangolo/fastapi/pull/1975) by [@JulianMaurin-BM](https://github.com/JulianMaurin-BM).
* Initialize Turkish translations. PR [#1905](https://github.com/tiangolo/fastapi/pull/1905) by [@ycd](https://github.com/ycd).
### Internal
* Improve docs maintainability by updating `hl_lines` syntax to use ranges. PR [#1863](https://github.com/tiangolo/fastapi/pull/1863) by [@la-mar](https://github.com/la-mar).
## 0.61.0
### Features
* Add support for injecting `HTTPConnection` (as `Request` and `WebSocket`). Useful for sharing app state in dependencies. PR [#1827](https://github.com/tiangolo/fastapi/pull/1827) by [@nsidnev](https://github.com/nsidnev).
* Export `WebSocketDisconnect` and add example handling WebSocket disconnections to docs. PR [#1822](https://github.com/tiangolo/fastapi/pull/1822) by [@rkbeatss](https://github.com/rkbeatss).
### Breaking Changes
* Require Pydantic > `1.0.0`.
* Remove support for deprecated Pydantic `0.32.2`. This improves maintainability and allows new features.
* In `FastAPI` and `APIRouter`:
* Remove *path operation decorators* related/deprecated parameter `response_model_skip_defaults` (use `response_model_exclude_unset` instead).
* Change *path operation decorators* parameter default for `response_model_exclude` from `set()` to `None` (as is in Pydantic).
* In `encoders.jsonable_encoder`:
* Remove deprecated `skip_defaults`, use instead `exclude_unset`.
* Set default of `exclude` from `set()` to `None` (as is in Pydantic).
* PR [#1862](https://github.com/tiangolo/fastapi/pull/1862).
* In `encoders.jsonable_encoder` remove parameter `sqlalchemy_safe`.
* It was an early hack to allow returning SQLAlchemy models, but it was never documented, and the recommended way is using Pydantic's `orm_mode` as described in the tutorial: [SQL (Relational) Databases](https://fastapi.tiangolo.com/tutorial/sql-databases/).
* PR [#1864](https://github.com/tiangolo/fastapi/pull/1864).
### Docs
* Add link to the course by TestDriven.io: [Test-Driven Development with FastAPI and Docker](https://testdriven.io/courses/tdd-fastapi/). PR [#1860](https://github.com/tiangolo/fastapi/pull/1860).
* Fix empty log message in docs example about handling errors. PR [#1815](https://github.com/tiangolo/fastapi/pull/1815) by [@manlix](https://github.com/manlix).
* Reword text to reduce ambiguity while not being gender-specific. PR [#1824](https://github.com/tiangolo/fastapi/pull/1824) by [@Mause](https://github.com/Mause).
### Internal
* Add Flake8 linting. Original PR [#1774](https://github.com/tiangolo/fastapi/pull/1774) by [@MashhadiNima](https://github.com/MashhadiNima).
* Disable Gitter bot, as it's currently broken, and Gitter's response doesn't show the problem. PR [#1853](https://github.com/tiangolo/fastapi/pull/1853).
## 0.60.2

View File

@@ -2,7 +2,7 @@
You can define background tasks to be run *after* returning a response.
This is useful for operations that need to happen after a request, but that the client doesn't really have to be waiting for the operation to complete before receiving his response.
This is useful for operations that need to happen after a request, but that the client doesn't really have to be waiting for the operation to complete before receiving the response.
This includes, for example:
@@ -15,7 +15,7 @@ This includes, for example:
First, import `BackgroundTasks` and define a parameter in your *path operation function* with a type declaration of `BackgroundTasks`:
```Python hl_lines="1 13"
```Python hl_lines="1 13"
{!../../../docs_src/background_tasks/tutorial001.py!}
```
@@ -33,7 +33,7 @@ In this case, the task function will write to a file (simulating sending an emai
And as the write operation doesn't use `async` and `await`, we define the function with normal `def`:
```Python hl_lines="6 7 8 9"
```Python hl_lines="6-9"
{!../../../docs_src/background_tasks/tutorial001.py!}
```
@@ -57,7 +57,7 @@ Using `BackgroundTasks` also works with the dependency injection system, you can
**FastAPI** knows what to do in each case and how to re-use the same object, so that all the background tasks are merged together and are run in the background afterwards:
```Python hl_lines="13 15 22 25"
```Python hl_lines="13 15 22 25"
{!../../../docs_src/background_tasks/tutorial002.py!}
```
@@ -81,7 +81,7 @@ You can see more details in <a href="https://www.starlette.io/background/" class
## Caveat
If you need to perform heavy background computation and you don't necessarily need it to be run by the same process (for example, you don't need to share memory, variables, etc), you might benefit from using other bigger tools like <a href="http://www.celeryproject.org/" class="external-link" target="_blank">Celery</a>.
If you need to perform heavy background computation and you don't necessarily need it to be run by the same process (for example, you don't need to share memory, variables, etc), you might benefit from using other bigger tools like <a href="https://docs.celeryproject.org" class="external-link" target="_blank">Celery</a>.
They tend to require more complex configurations, a message/job queue manager, like RabbitMQ or Redis, but they allow you to run background tasks in multiple processes, and especially, in multiple servers.

View File

@@ -16,14 +16,18 @@ Let's say you have a file structure like this:
├── app
│   ├── __init__.py
│   ├── main.py
│   ├── dependencies.py
│   └── routers
│   │ ├── __init__.py
│   │ ├── items.py
│   │ └── users.py
│   └── internal
│   ├── __init__.py
│   ── items.py
│   └── users.py
│   ── admin.py
```
!!! tip
There are two `__init__.py` files: one in each directory or subdirectory.
There are several `__init__.py` files: one in each directory or subdirectory.
This is what allows importing code from one file into another.
@@ -33,18 +37,33 @@ Let's say you have a file structure like this:
from app.routers import items
```
* The `app` directory contains everything.
* This `app` directory has an empty file `app/__init__.py`.
* So, the `app` directory is a "Python package" (a collection of "Python modules").
* The `app` directory also has a `app/main.py` file.
* As it is inside a Python package directory (because there's a file `__init__.py`), it is a "module" of that package: `app.main`.
* There's a subdirectory `app/routers/`.
* The subdirectory `app/routers` also has an empty file `__init__.py`.
* So, it is a "Python subpackage".
* The file `app/routers/items.py` is beside the `app/routers/__init__.py`.
* So, it's a submodule: `app.routers.items`.
* The file `app/routers/users.py` is beside the `app/routers/__init__.py`.
* So, it's a submodule: `app.routers.users`.
* The `app` directory contains everything. And it has an empty file `app/__init__.py`, so it is a "Python package" (a collection of "Python modules"): `app`.
* It contains an `app/main.py` file. As it is inside a Python package (a directory with a file `__init__.py`), it is a "module" of that package: `app.main`.
* There's also an `app/dependencies.py` file, just like `app/main.py`, it is a "module": `app.dependencies`.
* There's a subdirectory `app/routers/` with another file `__init__.py`, so it's a "Python subpackage": `app.routers`.
* The file `app/routers/items.py` is inside a package, `app/routers/`, so, it's a submodule: `app.routers.items`.
* The same with `app/routers/users.py`, it's another submodule: `app.routers.users`.
* There's also a subdirectory `app/internal/` with another file `__init__.py`, so it's another "Python subpackage": `app.internal`.
* And the file `app/internal/admin.py` is another submodule: `app.internal.admin`.
<img src="/img/tutorial/bigger-applications/package.svg">
The same file structure with comments:
```
.
├── app # "app" is a Python package
│   ├── __init__.py # this file makes "app" a "Python package"
│   ├── main.py # "main" module, e.g. import app.main
│   ├── dependencies.py # "dependencies" module, e.g. import app.dependencies
│   └── routers # "routers" is a "Python subpackage"
│   │ ├── __init__.py # makes "routers" a "Python subpackage"
│   │ ├── items.py # "items" submodule, e.g. import app.routers.items
│   │ └── users.py # "users" submodule, e.g. import app.routers.users
│   └── internal # "internal" is a "Python subpackage"
│   ├── __init__.py # makes "internal" a "Python subpackage"
│   └── admin.py # "admin" submodule, e.g. import app.internal.admin
```
## `APIRouter`
@@ -60,7 +79,7 @@ You can create the *path operations* for that module using `APIRouter`.
You import it and create an "instance" the same way you would with the class `FastAPI`:
```Python hl_lines="1 3"
```Python hl_lines="1 3"
{!../../../docs_src/bigger_applications/app/routers/users.py!}
```
@@ -70,7 +89,7 @@ And then you use it to declare your *path operations*.
Use it the same way you would use the `FastAPI` class:
```Python hl_lines="6 11 16"
```Python hl_lines="6 11 16"
{!../../../docs_src/bigger_applications/app/routers/users.py!}
```
@@ -78,16 +97,33 @@ You can think of `APIRouter` as a "mini `FastAPI`" class.
All the same options are supported.
All the same parameters, responses, dependencies, tags, etc.
All the same `parameters`, `responses`, `dependencies`, `tags`, etc.
!!! tip
In this example, the variable is called `router`, but you can name it however you want.
We are going to include this `APIrouter` in the main `FastAPI` app, but first, let's add another `APIRouter`.
We are going to include this `APIRouter` in the main `FastAPI` app, but first, let's check the dependencies and another `APIRouter`.
## Dependencies
We see that we are going to need some dependencies used in several places of the application.
So we put them in their own `dependencies` module (`app/dependencies.py`).
We will now use a simple dependency to read a custom `X-Token` header:
```Python hl_lines="1 4-6"
{!../../../docs_src/bigger_applications/app/dependencies.py!}
```
!!! tip
We are using an invented header to simplify this example.
But in real cases you will get better results using the integrated [Security utilities](./security/index.md){.internal-link target=_blank}.
## Another module with `APIRouter`
Let's say you also have the endpoints dedicated to handling "Items" from your application in the module at `app/routers/items.py`.
Let's say you also have the endpoints dedicated to handling "items" from your application in the module at `app/routers/items.py`.
You have *path operations* for:
@@ -96,24 +132,148 @@ You have *path operations* for:
It's all the same structure as with `app/routers/users.py`.
But let's say that this time we are more lazy.
But we want to be smarter and simplify the code a bit.
And we don't want to have to explicitly type `/items/` and `tags=["items"]` in every *path operation* (we will be able to do it later):
We know all the *path operations* in this module have the same:
```Python hl_lines="6 11"
* Path `prefix`: `/items`.
* `tags`: (just one tag: `items`).
* Extra `responses`.
* `dependencies`: they all need that `X-Token` dependency we created.
So, instead of adding all that to each *path operation*, we can add it to the `APIRouter`.
```Python hl_lines="5-10 16 21"
{!../../../docs_src/bigger_applications/app/routers/items.py!}
```
As the path of each *path operation* has to start with `/`, like in:
```Python hl_lines="1"
@router.get("/{item_id}")
async def read_item(item_id: str):
...
```
...the prefix must not include a final `/`.
So, the prefix in this case is `/items`.
We can also add a list of `tags` and extra `responses` that will be applied to all the *path operations* included in this router.
And we can add a list of `dependencies` that will be added to all the *path operations* in the router and will be executed/solved for each request made to them.
!!! tip
Note that, much like [dependencies in *path operation decorators*](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, no value will be passed to your *path operation function*.
The end result is that the item paths are now:
* `/items/`
* `/items/{item_id}`
...as we intended.
* They will be marked with a list of tags that contain a single string `"items"`.
* These "tags" are especially useful for the automatic interactive documentation systems (using OpenAPI).
* All of them will include the predefined `responses`.
* All these *path operations* will have the list of `dependencies` evaluated/executed before them.
* If you also declare dependencies in a specific *path operation*, **they will be executed too**.
* The router dependencies are executed first, then the [`dependencies` in the decorator](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, and then the normal parameter dependencies.
* You can also add [`Security` dependencies with `scopes`](../advanced/security/oauth2-scopes.md){.internal-link target=_blank}.
!!! tip
Having `dependencies` in the `APIRouter` can be used, for example, to require authentication for a whole group of *path operations*. Even if the dependencies are not added individually to each one of them.
!!! check
The `prefix`, `tags`, `responses`, and `dependencies` parameters are (as in many other cases) just a feature from **FastAPI** to help you avoid code duplication.
### Import the dependencies
This codes lives in the module `app.routers.items`, the file `app/routers/items.py`.
And we need to get the dependency function from the module `app.dependencies`, the file `app/dependencies.py`.
So we use a relative import with `..` for the dependencies:
```Python hl_lines="3"
{!../../../docs_src/bigger_applications/app/routers/items.py!}
```
#### How relative imports work
!!! tip
If you know perfectly how imports work, continue to the next section below.
A single dot `.`, like in:
```Python
from .dependencies import get_token_header
```
would mean:
* Starting in the same package that this module (the file `app/routers/items.py`) lives in (the directory `app/routers/`)...
* find the module `dependencies` (an imaginary file at `app/routers/dependencies.py`)...
* and from it, import the function `get_token_header`.
But that file doesn't exist, our dependencies are in a file at `app/dependencies.py`.
Remember how our app/file structure looks like:
<img src="/img/tutorial/bigger-applications/package.svg">
---
The two dots `..`, like in:
```Python
from ..dependencies import get_token_header
```
mean:
* Starting in the same package that this module (the file `app/routers/items.py`) lives in (the directory `app/routers/`)...
* go to the parent package (the directory `app/`)...
* and in there, find the module `dependencies` (the file at `app/routers/dependencies.py`)...
* and from it, import the function `get_token_header`.
That works correctly! 🎉
---
The same way, if we had used three dots `...`, like in:
```Python
from ...dependencies import get_token_header
```
that would mean:
* Starting in the same package that this module (the file `app/routers/items.py`) lives in (the directory `app/routers/`)...
* go to the parent package (the directory `app/`)...
* then go to the parent of that package (there's no parent package, `app` is the top level 😱)...
* and in there, find the module `dependencies` (the file at `app/routers/dependencies.py`)...
* and from it, import the function `get_token_header`.
That would refer to some package above `app/`, with its own file `__init__.py`, etc. But we don't have that. So, that would throw an error in our example. 🚨
But now you know how it works, so you can use relative imports in your own apps no matter how complex they are. 🤓
### Add some custom `tags`, `responses`, and `dependencies`
We are not adding the prefix `/items/` nor the `tags=["items"]` to add them later.
We are not adding the prefix `/items` nor the `tags=["items"]` to each *path operation* because we added them to the `APIRouter`.
But we can add custom `tags` and `responses` that will be applied to a specific *path operation*:
But we can still add _more_ `tags` that will be applied to a specific *path operation*, and also some extra `responses` specific to that *path operation*:
```Python hl_lines="18 19"
```Python hl_lines="30-31"
{!../../../docs_src/bigger_applications/app/routers/items.py!}
```
!!! tip
This last path operation will have the combination of tags: `["items", "custom"]`.
And it will also have both responses in the documentation, one for `404` and one for `403`.
## The main `FastAPI`
Now, let's see the module at `app/main.py`.
@@ -122,25 +282,27 @@ Here's where you import and use the class `FastAPI`.
This will be the main file in your application that ties everything together.
And as most of your logic will now live in its own specific module, the main file will be quite simple.
### Import `FastAPI`
You import and create a `FastAPI` class as normally:
You import and create a `FastAPI` class as normally.
```Python hl_lines="1 5"
And we can even declare [global dependencies](dependencies/global-dependencies.md){.internal-link target=_blank} that will be combined with the dependencies for each `APIRouter`:
```Python hl_lines="1 3 7"
{!../../../docs_src/bigger_applications/app/main.py!}
```
### Import the `APIRouter`
But this time we are not adding *path operations* directly with the `FastAPI` `app`.
Now we import the other submodules that have `APIRouter`s:
We import the other submodules that have `APIRouter`s:
```Python hl_lines="3"
```Python hl_lines="5"
{!../../../docs_src/bigger_applications/app/main.py!}
```
As the file `app/routers/items.py` is part of the same Python package, we can import it using "dot notation".
As the files `app/routers/users.py` and `app/routers/items.py` are submodules that are part of the same Python package `app`, we can use a single dot `.` to import them using "relative imports".
### How the importing works
@@ -156,7 +318,9 @@ Means:
* look for the subpackage `routers` (the directory at `app/routers/`)...
* and from it, import the submodule `items` (the file at `app/routers/items.py`) and `users` (the file at `app/routers/users.py`)...
The module `items` will have a variable `router` (`items.router`). This is the same one we created in the file `app/routers/items.py`. It's an `APIRouter`. The same for the module `users`.
The module `items` will have a variable `router` (`items.router`). This is the same one we created in the file `app/routers/items.py`, it's an `APIRouter` object.
And then we do the same for the module `users`.
We could also import them like:
@@ -165,9 +329,17 @@ from app.routers import items, users
```
!!! info
The first version is a "relative import".
The first version is a "relative import":
The second version is an "absolute import".
```Python
from .routers import items, users
```
The second version is an "absolute import":
```Python
from app.routers import items, users
```
To learn more about Python Packages and Modules, read <a href="https://docs.python.org/3/tutorial/modules.html" class="external-link" target="_blank">the official Python documentation about Modules</a>.
@@ -188,22 +360,24 @@ The `router` from `users` would overwrite the one from `items` and we wouldn't b
So, to be able to use both of them in the same file, we import the submodules directly:
```Python hl_lines="3"
```Python hl_lines="4"
{!../../../docs_src/bigger_applications/app/main.py!}
```
### Include an `APIRouter`
### Include the `APIRouter`s for `users` and `items`
Now, let's include the `router` from the submodule `users`:
Now, let's include the `router`s from the submodules `users` and `items`:
```Python hl_lines="13"
```Python hl_lines="10-11"
{!../../../docs_src/bigger_applications/app/main.py!}
```
!!! info
`users.router` contains the `APIRouter` inside of the file `app/routers/users.py`.
With `app.include_router()` we can add an `APIRouter` to the main `FastAPI` application.
And `items.router` contains the `APIRouter` inside of the file `app/routers/items.py`.
With `app.include_router()` we can add each `APIRouter` to the main `FastAPI` application.
It will include all the routes from that router as part of it.
@@ -217,67 +391,52 @@ It will include all the routes from that router as part of it.
This will take microseconds and will only happen at startup.
So it won't affect performance.
So it won't affect performance.
### Include an `APIRouter` with a `prefix`, `tags`, `responses`, and `dependencies`
### Include an `APIRouter` with a custom `prefix`, `tags`, `responses`, and `dependencies`
Now, let's include the router from the `items` submodule.
Now, let's imagine your organization gave you the `app/internal/admin.py` file.
But, remember that we were lazy and didn't add `/items/` nor `tags` to all the *path operations*?
It contains an `APIRouter` with some admin *path operations* that your organization shares between several projects.
We can add a prefix to all the *path operations* using the parameter `prefix` of `app.include_router()`.
For this example it will be super simple. But let's say that because it is shared with other projects in the organization, we cannot modify it and add a `prefix`, `dependencies`, `tags`, etc. directly to the `APIRouter`:
As the path of each *path operation* has to start with `/`, like in:
```Python hl_lines="1"
@router.get("/{item_id}")
async def read_item(item_id: str):
...
```Python hl_lines="3"
{!../../../docs_src/bigger_applications/app/internal/admin.py!}
```
...the prefix must not include a final `/`.
But we still want to set a custom `prefix` when including the `APIRouter` so that all its *path operations* start with `/admin`, we want to secure it with the `dependencies` we already have for this project, and we want to include `tags` and `responses`.
So, the prefix in this case would be `/items`.
We can declare all that without having to modify the original `APIRouter` by passing those parameters to `app.include_router()`:
We can also add a list of `tags` that will be applied to all the *path operations* included in this router.
And we can add predefined `responses` that will be included in all the *path operations* too.
And we can add a list of `dependencies` that will be added to all the *path operations* in the router and will be executed/solved for each request made to them. Note that, much like dependencies in *path operation decorators*, no value will be passed to your *path operation function*.
```Python hl_lines="8 9 10 14 15 16 17 18 19 20"
```Python hl_lines="14-17"
{!../../../docs_src/bigger_applications/app/main.py!}
```
The end result is that the item paths are now:
That way, the original `APIRouter` will keep unmodified, so we can still share that same `app/internal/admin.py` file with other projects in the organization.
* `/items/`
* `/items/{item_id}`
The result is that in our app, each of the *path operations* from the `admin` module will have:
...as we intended.
* The prefix `/admin`.
* The tag `admin`.
* The dependency `get_token_header`.
* The response `418`. 🍵
* They will be marked with a list of tags that contain a single string `"items"`.
* The *path operation* that declared a `"custom"` tag will have both tags, `items` and `custom`.
* These "tags" are especially useful for the automatic interactive documentation systems (using OpenAPI).
* All of them will include the predefined `responses`.
* The *path operation* that declared a custom `403` response will have both the predefined responses (`404`) and the `403` declared in it directly.
* All these *path operations* will have the list of `dependencies` evaluated/executed before them.
* If you also declare dependencies in a specific *path operation*, **they will be executed too**.
* The router dependencies are executed first, then the [`dependencies` in the decorator](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, and then the normal parameter dependencies.
* You can also add [`Security` dependencies with `scopes`](../advanced/security/oauth2-scopes.md){.internal-link target=_blank}.
But that will only affect that `APIRouter` in our app, not in any other code that uses it.
!!! tip
Having `dependencies` in a decorator can be used, for example, to require authentication for a whole group of *path operations*. Even if the dependencies are not added individually to each one of them.
So, for example, other projects could use the same `APIRouter` with a different authentication method.
!!! check
The `prefix`, `tags`, `responses` and `dependencies` parameters are (as in many other cases) just a feature from **FastAPI** to help you avoid code duplication.
### Include a *path operation*
!!! tip
You could also add *path operations* directly, for example with: `@app.get(...)`.
We can also add *path operations* directly to the `FastAPI` app.
Apart from `app.include_router()`, in the same **FastAPI** app.
Here we do it... just to show that we can 🤷:
It would still work the same.
```Python hl_lines="21-23"
{!../../../docs_src/bigger_applications/app/main.py!}
```
and it will work correctly, together with all the other *path operations* added with `app.include_router()`.
!!! info "Very Technical Details"
**Note**: this is a very technical detail that you probably can **just skip**.
@@ -317,3 +476,13 @@ You can also use `.include_router()` multiple times with the *same* router using
This could be useful, for example, to expose the same API under different prefixes, e.g. `/api/v1` and `/api/latest`.
This is an advanced usage that you might not really need, but it's there in case you do.
## Include an `APIRouter` in another
The same way you can include an `APIRouter` in a `FastAPI` application, you can include an `APIRouter` in another `APIRouter` using:
```Python
router.include_router(other_router)
```
Make sure you do it before including `router` in the `FastAPI` app, so that the *path operations* from `other_router` are also included.

View File

@@ -17,7 +17,7 @@ First, you have to import it:
You can then use `Field` with model attributes:
```Python hl_lines="11 12 13 14"
```Python hl_lines="11-14"
{!../../../docs_src/body_fields/tutorial001.py!}
```

View File

@@ -8,7 +8,7 @@ First, of course, you can mix `Path`, `Query` and request body parameter declara
And you can also declare body parameters as optional, by setting the default to `None`:
```Python hl_lines="19 20 21"
```Python hl_lines="19-21"
{!../../../docs_src/body_multiple_params/tutorial001.py!}
```

View File

@@ -55,7 +55,7 @@ And Python has a special data type for sets of unique items, the `set`.
Then we can import `Set` and declare `tags` as a `set` of `str`:
```Python hl_lines="1 14"
```Python hl_lines="1 14"
{!../../../docs_src/body_nested_models/tutorial003.py!}
```
@@ -79,7 +79,7 @@ All that, arbitrarily nested.
For example, we can define an `Image` model:
```Python hl_lines="9 10 11"
```Python hl_lines="9-11"
{!../../../docs_src/body_nested_models/tutorial004.py!}
```
@@ -122,7 +122,7 @@ To see all the options you have, checkout the docs for <a href="https://pydantic
For example, as in the `Image` model we have a `url` field, we can declare it to be instead of a `str`, a Pydantic's `HttpUrl`:
```Python hl_lines="4 10"
```Python hl_lines="4 10"
{!../../../docs_src/body_nested_models/tutorial005.py!}
```
@@ -169,7 +169,7 @@ This will expect (convert, validate, document, etc) a JSON body like:
You can define arbitrarily deeply nested models:
```Python hl_lines="9 14 20 23 27"
```Python hl_lines="9 14 20 23 27"
{!../../../docs_src/body_nested_models/tutorial007.py!}
```

View File

@@ -6,7 +6,7 @@ To update an item you can use the <a href="https://developer.mozilla.org/en-US/d
You can use the `jsonable_encoder` to convert the input data to data that can be stored as JSON (e.g. with a NoSQL database). For example, converting `datetime` to `str`.
```Python hl_lines="30 31 32 33 34 35"
```Python hl_lines="30-35"
{!../../../docs_src/body_updates/tutorial001.py!}
```
@@ -82,7 +82,7 @@ In summary, to apply partial updates you would:
* Save the data to your DB.
* Return the updated model.
```Python hl_lines="30 31 32 33 34 35 36 37"
```Python hl_lines="30-37"
{!../../../docs_src/body_updates/tutorial002.py!}
```

View File

@@ -29,7 +29,7 @@ Then you declare your data model as a class that inherits from `BaseModel`.
Use standard Python types for all the attributes:
```Python hl_lines="7 8 9 10 11"
```Python hl_lines="7-11"
{!../../../docs_src/body/tutorial001.py!}
```
@@ -75,7 +75,7 @@ With just that Python type declaration, **FastAPI** will:
* If the data is invalid, it will return a nice and clear error, indicating exactly where and what was the incorrect data.
* Give you the received data in the parameter `item`.
* As you declared it in the function to be of type `Item`, you will also have all the editor support (completion, etc) for all of the attributes and their types.
* Generate <a href="http://json-schema.org" class="external-link" target="_blank">JSON Schema</a> definitions for your model, you can also use them anywhere else you like if it makes sense for your project.
* Generate <a href="https://json-schema.org" class="external-link" target="_blank">JSON Schema</a> definitions for your model, you can also use them anywhere else you like if it makes sense for your project.
* Those schemas will be part of the generated OpenAPI schema, and used by the automatic documentation <abbr title="User Interfaces">UIs</abbr>.
## Automatic docs
@@ -131,11 +131,11 @@ Inside of the function, you can access all the attributes of the model object di
## Request body + path parameters
You can declare path parameters and body requests at the same time.
You can declare path parameters and request body at the same time.
**FastAPI** will recognize that the function parameters that match path parameters should be **taken from the path**, and that function parameters that are declared to be Pydantic models should be **taken from the request body**.
```Python hl_lines="17 18"
```Python hl_lines="17-18"
{!../../../docs_src/body/tutorial003.py!}
```

View File

@@ -46,7 +46,7 @@ You can also specify if your backend allows:
* Specific HTTP methods (`POST`, `PUT`) or all of them with the wildcard `"*"`.
* Specific HTTP headers or all of them with the wildcard `"*"`.
```Python hl_lines="2 6 7 8 9 10 11 13 14 15 16 17 18 19"
```Python hl_lines="2 6-11 13-19"
{!../../../docs_src/cors/tutorial001.py!}
```
@@ -55,10 +55,10 @@ The default parameters used by the `CORSMiddleware` implementation are restricti
The following arguments are supported:
* `allow_origins` - A list of origins that should be permitted to make cross-origin requests. E.g. `['https://example.org', 'https://www.example.org']`. You can use `['*']` to allow any origin.
* `allow_origin_regex` - A regex string to match against origins that should be permitted to make cross-origin requests. eg. `'https://.*\.example\.org'`.
* `allow_origin_regex` - A regex string to match against origins that should be permitted to make cross-origin requests. e.g. `'https://.*\.example\.org'`.
* `allow_methods` - A list of HTTP methods that should be allowed for cross-origin requests. Defaults to `['GET']`. You can use `['*']` to allow all standard methods.
* `allow_headers` - A list of HTTP request headers that should be supported for cross-origin requests. Defaults to `[]`. You can use `['*']` to allow all headers. The `Accept`, `Accept-Language`, `Content-Language` and `Content-Type` headers are always allowed for CORS requests.
* `allow_credentials` - Indicate that cookies should be supported for cross-origin requests. Defaults to `False`.
* `allow_credentials` - Indicate that cookies should be supported for cross-origin requests. Defaults to `False`. Also, `allow_origins` cannot be set to `['*']` for credentials to be allowed, origins must be specified.
* `expose_headers` - Indicate any response headers that should be made accessible to the browser. Defaults to `[]`.
* `max_age` - Sets a maximum time in seconds for browsers to cache CORS responses. Defaults to `600`.

View File

@@ -6,7 +6,7 @@ You can connect the debugger in your editor, for example with Visual Studio Code
In your FastAPI application, import and run `uvicorn` directly:
```Python hl_lines="1 15"
```Python hl_lines="1 15"
{!../../../docs_src/debugging/tutorial001.py!}
```

View File

@@ -71,7 +71,7 @@ That also applies to callables with no parameters at all. The same as it would b
Then, we can change the dependency "dependable" `common_parameters` from above to the class `CommonQueryParams`:
```Python hl_lines="11 12 13 14 15"
```Python hl_lines="11-15"
{!../../../docs_src/dependencies/tutorial002.py!}
```

View File

@@ -27,6 +27,11 @@ These dependencies will be executed/solved the same way normal dependencies. But
It might also help avoid confusion for new developers that see an unused parameter in your code and could think it's unnecessary.
!!! info
In this example we use invented custom headers `X-Key` and `X-Token`.
But in real cases, when implementing security, you would get more benefits from using the integrated [Security utilities (the next chapter)](../security/index.md){.internal-link target=_blank}.
## Dependencies errors and return values
You can use the same dependency *functions* you use normally.
@@ -35,7 +40,7 @@ You can use the same dependency *functions* you use normally.
They can declare request requirements (like headers) or other sub-dependencies:
```Python hl_lines="6 11"
```Python hl_lines="6 11"
{!../../../docs_src/dependencies/tutorial006.py!}
```
@@ -43,7 +48,7 @@ They can declare request requirements (like headers) or other sub-dependencies:
These dependencies can `raise` exceptions, the same as normal dependencies:
```Python hl_lines="8 13"
```Python hl_lines="8 13"
{!../../../docs_src/dependencies/tutorial006.py!}
```
@@ -53,10 +58,14 @@ And they can return values or not, the values won't be used.
So, you can re-use a normal dependency (that returns a value) you already use somewhere else, and even though the value won't be used, the dependency will be executed:
```Python hl_lines="9 14"
```Python hl_lines="9 14"
{!../../../docs_src/dependencies/tutorial006.py!}
```
## Dependencies for a group of *path operations*
Later, when reading about how to structure bigger applications ([Bigger Applications - Multiple Files](../../tutorial/bigger-applications.md){.internal-link target=_blank}), possibly with multiple files, you will learn how to declare a single `dependencies` parameter for a group of *path operations*.
## Global Dependencies
Next we will see how to add dependencies to the whole `FastAPI` application, so that they apply to each *path operation*.

View File

@@ -32,7 +32,7 @@ For example, you could use this to create a database session and close it after
Only the code prior to and including the `yield` statement is executed before sending a response:
```Python hl_lines="2 3 4"
```Python hl_lines="2-4"
{!../../../docs_src/dependencies/tutorial007.py!}
```
@@ -44,7 +44,7 @@ The yielded value is what is injected into *path operations* and other dependenc
The code following the `yield` statement is executed after the response has been delivered:
```Python hl_lines="5 6"
```Python hl_lines="5-6"
{!../../../docs_src/dependencies/tutorial007.py!}
```
@@ -63,7 +63,7 @@ So, you can look for that specific exception inside the dependency with `except
In the same way, you can use `finally` to make sure the exit steps are executed, no matter if there was an exception or not.
```Python hl_lines="3 5"
```Python hl_lines="3 5"
{!../../../docs_src/dependencies/tutorial007.py!}
```
@@ -75,7 +75,7 @@ You can have sub-dependencies and "trees" of sub-dependencies of any size and sh
For example, `dependency_c` can have a dependency on `dependency_b`, and `dependency_b` on `dependency_a`:
```Python hl_lines="4 12 20"
```Python hl_lines="4 12 20"
{!../../../docs_src/dependencies/tutorial008.py!}
```
@@ -85,7 +85,7 @@ In this case `dependency_c`, to execute its exit code, needs the value from `dep
And, in turn, `dependency_b` needs the value from `dependency_a` (here named `dep_a`) to be available for its exit code.
```Python hl_lines="16 17 24 25"
```Python hl_lines="16-17 24-25"
{!../../../docs_src/dependencies/tutorial008.py!}
```
@@ -207,7 +207,7 @@ In Python, you can create Context Managers by <a href="https://docs.python.org/3
You can also use them inside of **FastAPI** dependencies with `yield` by using
`with` or `async with` statements inside of the dependency function:
```Python hl_lines="1 2 3 4 5 6 7 8 9 13"
```Python hl_lines="1-9 13"
{!../../../docs_src/dependencies/tutorial010.py!}
```

View File

@@ -0,0 +1,17 @@
# Global Dependencies
For some types of applications you might want to add dependencies to the whole application.
Similar to the way you can [add `dependencies` to the *path operation decorators*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank}, you can add them to the `FastAPI` application.
In that case, they will be applied to all the *path operations* in the application:
```Python hl_lines="15"
{!../../../docs_src/dependencies/tutorial012.py!}
```
And all the ideas in the section about [adding `dependencies` to the *path operation decorators*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} still apply, but in this case, to all of the *path operations* in the app.
## Dependencies for groups of *path operations*
Later, when reading about how to structure bigger applications ([Bigger Applications - Multiple Files](../../tutorial/bigger-applications.md){.internal-link target=_blank}), possibly with multiple files, you will learn how to declare a single `dependencies` parameter for a group of *path operations*.

View File

@@ -31,7 +31,7 @@ Let's first focus on the dependency.
It is just a function that can take all the same parameters that a *path operation function* can take:
```Python hl_lines="8 9"
```Python hl_lines="8-9"
{!../../../docs_src/dependencies/tutorial001.py!}
```

View File

@@ -10,7 +10,7 @@ They can be as **deep** as you need them to be.
You could create a first dependency ("dependable") like:
```Python hl_lines="8 9"
```Python hl_lines="8-9"
{!../../../docs_src/dependencies/tutorial005.py!}
```

View File

@@ -20,7 +20,7 @@ You can use `jsonable_encoder` for that.
It receives an object, like a Pydantic model, and returns a JSON compatible version:
```Python hl_lines="5 22"
```Python hl_lines="5 22"
{!../../../docs_src/encoder/tutorial001.py!}
```

View File

@@ -55,12 +55,12 @@ Here are some of the additional data types you can use:
Here's an example *path operation* with parameters using some of the above types.
```Python hl_lines="1 3 12 13 14 15 16"
```Python hl_lines="1 3 12-16"
{!../../../docs_src/extra_data_types/tutorial001.py!}
```
Note that the parameters inside the function have their natural data type, and you can, for example, perform normal date manipulations, like:
```Python hl_lines="18 19"
```Python hl_lines="18-19"
{!../../../docs_src/extra_data_types/tutorial001.py!}
```

View File

@@ -17,7 +17,7 @@ This is especially the case for user models, because:
Here's a general idea of how the models could look like with their password fields and the places where they are used:
```Python hl_lines="9 11 16 22 24 29 30 33 34 35 40 41"
```Python hl_lines="9 11 16 22 24 29-30 33-35 40-41"
{!../../../docs_src/extra_models/tutorial001.py!}
```
@@ -150,7 +150,7 @@ All the data conversion, validation, documentation, etc. will still work as norm
That way, we can declare just the differences between the models (with plaintext `password`, with `hashed_password` and without password):
```Python hl_lines="9 15 16 19 20 23 24"
```Python hl_lines="9 15-16 19-20 23-24"
{!../../../docs_src/extra_models/tutorial002.py!}
```
@@ -165,7 +165,7 @@ To do that, use the standard Python type hint <a href="https://docs.python.org/3
!!! note
When defining a <a href="https://pydantic-docs.helpmanual.io/usage/types/#unions" class="external-link" target="_blank">`Union`</a>, include the most specific type first, followed by the less specific type. In the example below, the more specific `PlaneItem` comes before `CarItem` in `Union[PlaneItem, CarItem]`.
```Python hl_lines="1 14 15 18 19 20 33"
```Python hl_lines="1 14-15 18-20 33"
{!../../../docs_src/extra_models/tutorial003.py!}
```
@@ -175,7 +175,7 @@ The same way, you can declare responses of lists of objects.
For that, use the standard Python `typing.List`:
```Python hl_lines="1 20"
```Python hl_lines="1 20"
{!../../../docs_src/extra_models/tutorial004.py!}
```
@@ -187,7 +187,7 @@ This is useful if you don't know the valid field/attribute names (that would be
In this case, you can use `typing.Dict`:
```Python hl_lines="1 8"
```Python hl_lines="1 8"
{!../../../docs_src/extra_models/tutorial005.py!}
```

View File

@@ -47,7 +47,7 @@ In this example, when the client request an item by an ID that doesn't exist, ra
### The resulting response
If the client requests `http://example.com/items/foo` (an `item_id` `"foo"`), he will receive an HTTP status code of 200, and a JSON response of:
If the client requests `http://example.com/items/foo` (an `item_id` `"foo"`), that client will receive an HTTP status code of 200, and a JSON response of:
```JSON
{
@@ -55,7 +55,7 @@ If the client requests `http://example.com/items/foo` (an `item_id` `"foo"`), he
}
```
But if the client requests `http://example.com/items/bar` (a non-existent `item_id` `"bar"`), he will receive an HTTP status code of 404 (the "not found" error), and a JSON response of:
But if the client requests `http://example.com/items/bar` (a non-existent `item_id` `"bar"`), that client will receive an HTTP status code of 404 (the "not found" error), and a JSON response of:
```JSON
{
@@ -92,7 +92,7 @@ And you want to handle this exception globally with FastAPI.
You could add a custom exception handler with `@app.exception_handler()`:
```Python hl_lines="5 6 7 13 14 15 16 17 18 24"
```Python hl_lines="5-7 13-18 24"
{!../../../docs_src/handling_errors/tutorial003.py!}
```
@@ -129,7 +129,7 @@ To override it, import the `RequestValidationError` and use it with `@app.except
The exception handler will receive a `Request` and the exception.
```Python hl_lines="2 14 15 16"
```Python hl_lines="2 14-16"
{!../../../docs_src/handling_errors/tutorial004.py!}
```
@@ -179,7 +179,7 @@ The same way, you can override the `HTTPException` handler.
For example, you could want to return a plain text response instead of JSON for these errors:
```Python hl_lines="3 4 9 10 11 22"
```Python hl_lines="3-4 9-11 22"
{!../../../docs_src/handling_errors/tutorial004.py!}
```
@@ -209,7 +209,7 @@ Now try sending an invalid item like:
You will receive a response telling you that the data is invalid containing the received body:
```JSON hl_lines="12 13 14 15"
```JSON hl_lines="12-15"
{
"detail": [
{
@@ -256,7 +256,7 @@ You could also just want to use the exception somehow, but then use the same def
You can import and re-use the default exception handlers from `fastapi.exception_handlers`:
```Python hl_lines="2 3 4 5 15 21"
```Python hl_lines="2-5 15 21"
{!../../../docs_src/handling_errors/tutorial006.py!}
```

View File

@@ -13,7 +13,7 @@ You can set the:
To set them, use the parameters `title`, `description`, and `version`:
```Python hl_lines="4 5 6"
```Python hl_lines="4-6"
{!../../../docs_src/metadata/tutorial001.py!}
```
@@ -41,7 +41,7 @@ Let's try that in an example with tags for `users` and `items`.
Create metadata for your tags and pass it to the `openapi_tags` parameter:
```Python hl_lines="3 4 5 6 7 8 9 10 11 12 13 14 15 16 18"
```Python hl_lines="3-16 18"
{!../../../docs_src/metadata/tutorial004.py!}
```

View File

@@ -28,7 +28,7 @@ The middleware function receives:
* Then it returns the `response` generated by the corresponding *path operation*.
* You can then modify further the `response` before returning it.
```Python hl_lines="8 9 11 14"
```Python hl_lines="8-9 11 14"
{!../../../docs_src/middleware/tutorial001.py!}
```
@@ -50,7 +50,7 @@ And also after the `response` is generated, before returning it.
For example, you could add a custom header `X-Process-Time` containing the time in seconds that it took to process the request and generate a response:
```Python hl_lines="10 12 13"
```Python hl_lines="10 12-13"
{!../../../docs_src/middleware/tutorial001.py!}
```

View File

@@ -28,7 +28,7 @@ That status code will be used in the response and will be added to the OpenAPI s
You can add tags to your *path operation*, pass the parameter `tags` with a `list` of `str` (commonly just one `str`):
```Python hl_lines="17 22 27"
```Python hl_lines="17 22 27"
{!../../../docs_src/path_operation_configuration/tutorial002.py!}
```
@@ -40,7 +40,7 @@ They will be added to the OpenAPI schema and used by the automatic documentation
You can add a `summary` and `description`:
```Python hl_lines="20 21"
```Python hl_lines="20-21"
{!../../../docs_src/path_operation_configuration/tutorial003.py!}
```
@@ -50,7 +50,7 @@ As descriptions tend to be long and cover multiple lines, you can declare the *p
You can write <a href="https://en.wikipedia.org/wiki/Markdown" class="external-link" target="_blank">Markdown</a> in the docstring, it will be interpreted and displayed correctly (taking into account docstring indentation).
```Python hl_lines="19 20 21 22 23 24 25 26 27"
```Python hl_lines="19-27"
{!../../../docs_src/path_operation_configuration/tutorial004.py!}
```

View File

@@ -106,7 +106,7 @@ And you can also declare numeric validations:
* `le`: `l`ess than or `e`qual
!!! info
`Query`, `Path` and others you will see later subclasses of a common `Param` class (that you don't need to use).
`Query`, `Path`, and others you will see later are subclasses of a common `Param` class (that you don't need to use).
And all of them share the same all these same parameters of additional validation and metadata you have seen.

Some files were not shown because too many files have changed in this diff Show More