Compare commits

...

436 Commits

Author SHA1 Message Date
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
Sebastián Ramírez
79e08a2541 🔖 Release version 0.60.2 2020-08-08 20:23:16 +02:00
Sebastián Ramírez
1c9c80ba93 📝 Update release notes 2020-08-08 20:21:03 +02:00
Yağızcan Değirmenci
25cb05c876 ✏ Fix documentation typo in Query Parameters and String Validations (#1832) 2020-08-08 20:19:14 +02:00
Sebastián Ramírez
694fbab074 📝 Update release notes 2020-08-08 20:07:03 +02:00
Felix Böhm
2fd28434dd 📝 Add documentation about async tests (pytest-asyncio and httpx) (#1619)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-08-08 20:01:18 +02:00
Sebastián Ramírez
d15556b152 📝 Update release notes 2020-08-08 09:20:37 +02:00
Sebastián Ramírez
38d8bab770 Raise early when using form data without installing python-multipart (#1851)
* Check if Form exists and multipart is in virtual environment

* Remove unused import

* Move BodyFieldInfo check to separate helper function

* Fix type UploadFile to File for BodyFieldInfo check

* Working solution. Kind of nasty though.

* Use better method of determing if correct package imported

* Use better method of determing if correct package imported

* Add raising exceptions, update error messages

* Check if Form exists and multipart is in virtual environment

* Move BodyFieldInfo check to separate helper function

* Fix type UploadFile to File for BodyFieldInfo check

* Use better method of determing if correct package imported

* Add raising exceptions, update error messages
* Removed unused import, added comments

Co-authored-by: Christopher Nguyen <chrisngyn99@gmail.com>

* Updated what kind of exception will be thrown

* Add type annotations

Adds annotations to is_form_data

* Fix import order

* Add basic tests

* Fixed Travis tests

* Replace logging with fastapi logger

* Change AttributeError to ImportError to fix exception handling

* Fixing tests

* Catch ModuleNotFoundError first

Fix code coverage

* Update fastapi/dependencies/utils.py

Remove error spaces when printing

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

* Update fastapi/dependencies/utils.py

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

* Removed spaces in error printing

* ♻️ Refactor form data detection

*  Update/increase tests for incorrect multipart install

* 🔥 Remove deprecated Travis (moved to GitHub Actions)

Co-authored-by: yk396 <yk396@cornell.edu>
Co-authored-by: Christopher Nguyen <chrisngyn99@gmail.com>
Co-authored-by: Kai Chen <kaichen120@gmail.com>
Co-authored-by: Chris N <hello@chris-nguyen.me>
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
2020-08-08 09:14:10 +02:00
Sebastián Ramírez
52f0f8657e 📝 Update release notes 2020-08-03 19:28:49 +02:00
Sebastián Ramírez
aedf5c895a 👷 Re-enable Gitter releases bot (#1831) 2020-08-03 19:28:02 +02:00
Sebastián Ramírez
117f9e4abe 📝 Update release notes 2020-08-03 18:38:27 +02:00
s2s
604fea9fc1 📝 Add link in sql-databases.md tutorial to async-sql-databases.md in advanced section. (#1813)
* Add link in sql-databases.md tutorial section to async-sql-databases.md in advanced section.

* 🎨 Update note format

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-08-03 18:37:02 +02:00
Sebastián Ramírez
994bfd4591 📝 Update release notes 2020-08-03 18:27:03 +02:00
Eduard Iskandarov
02722923b1 ✏ Fix documentation typo in behind a proxy tutorial (#1807) 2020-08-03 18:25:01 +02:00
Sebastián Ramírez
d63a93429b 📝 Update release notes 2020-08-03 18:14:15 +02:00
Izabela Guerreiro
b93e216dc7 ✏ Fix typo in portuguese docs (#1795) 2020-08-03 18:12:30 +02:00
Sebastián Ramírez
95a29b6e67 📝 Update release notes 2020-08-03 18:05:05 +02:00
Sebastián Ramírez
272f01a153 🌐 Add Ukrainian language setup, without index translation (#1830) 2020-08-03 18:04:05 +02:00
Sebastián Ramírez
1a345ae7fc 📝 Update release notes 2020-08-03 17:41:50 +02:00
Marcelo Trylesinski
c5c138b8eb 📝 Update external links (#1786)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-08-03 17:39:48 +02:00
Sebastián Ramírez
da20e33414 📝 Update release notes 2020-08-03 17:26:12 +02:00
Henry Betts
7fbe3737bc 🐛 Fix encoding a Pydantic model that inherits from another with json_encoders (#1769) 2020-08-03 17:24:29 +02:00
Sebastián Ramírez
f63cec9c95 📝 Update release notes 2020-08-03 15:32:03 +02:00
Nima Mashhadi M. Reza
3063ad83ec Simplify and improve jsonable_encoder (#1754)
Co-authored-by: nimashadix <nimashadix@pop-os.localdomain>
2020-08-03 15:30:23 +02:00
Sebastián Ramírez
78680e5bee 📝 Update relase notes 2020-08-03 15:19:33 +02:00
Yurii Karabas
55b9faeb48 ♻ Simplify code syntax in several places (#1753)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-08-03 15:16:51 +02:00
Sebastián Ramírez
72645dfeab 📝 Update release notes 2020-08-03 14:30:25 +02:00
Nima Mashhadi M. Reza
3223de5598 🎨 Add typing.Optional to variables that accept None as value (#1731)
Co-authored-by: nimashadix <nimashadix@pop-os.localdomain>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-08-03 14:29:07 +02:00
Sebastián Ramírez
1afa4e8e75 📝 Update release notes 2020-08-03 13:50:22 +02:00
नवुले पवन कुमार राव
6fd3736da2 📝 Add article: Deploy FastAPI on Azure App Service (#1726) 2020-08-03 13:48:30 +02:00
Sebastián Ramírez
7e043e5e6f 📝 Update release notes 2020-08-03 10:46:33 +02:00
Smart
d1585c42b9 📝 Add external link to starlette docs for WebSocket testing (#1717)
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-08-03 10:45:22 +02:00
Sebastián Ramírez
fc494e3527 📝 Update release notes 2020-08-03 10:34:05 +02:00
Bloodielie
b344cc9415 ♻ Refactor and merge for loops in dependant creation (#1714)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-08-03 10:32:06 +02:00
Sebastián Ramírez
38b71a9298 📝 Update release notes 2020-08-03 09:55:21 +02:00
Francesco Frassinelli
769ee73240 📝 Add HTML media type to template docs (#1690)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-08-03 09:53:56 +02:00
Sebastián Ramírez
1df2f14c64 📝 Update release notes 2020-08-03 09:28:03 +02:00
Nils Lindemann
eab9a0e139 ✏ Fix typos and rewording in docs for security (#1678)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-08-03 09:27:02 +02:00
Sebastián Ramírez
b86ac6739a 📝 Update release notes 2020-08-03 09:13:17 +02:00
Nils Lindemann
9840d9e59d ✏ Fix typos in docs for dependencies (#1675)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-08-03 09:12:07 +02:00
Sebastián Ramírez
0ec52157df 📝 Update release notes 2020-08-03 08:46:50 +02:00
Bar Harel
f1c5330b65 🐛 Fix app.extra type annotation (#1659)
Co-authored-by: bar.harel <bar.harel@biocatch.com>
2020-08-03 08:43:04 +02:00
Sebastián Ramírez
306ec8de04 📝 Update release notes 2020-08-03 08:35:05 +02:00
Adrien Cacciaguerra
6d7c9893d4 ⬆️ Bump mkdocs-material (#1789) 2020-08-03 08:33:43 +02:00
Sebastián Ramírez
6264709054 📝 Update release notes 2020-08-03 08:11:00 +02:00
Sebastián Ramírez
76c2077f47 👷 Update docs previews, remove commit comments (#1826)
as previews use the latest commit from master
2020-08-03 08:09:58 +02:00
Izabela Guerreiro
9cc4428de3 Portuguese translation python-types 2020-07-26 23:00:28 -03:00
Sebastián Ramírez
a63b1efc29 📝 Update release notes 2020-07-22 10:29:49 +02:00
Sebastián Ramírez
9863c3fca8 🐛 Update GitHub action context var for Gitter bot (#1766) 2020-07-22 10:28:27 +02:00
Sebastián Ramírez
6fb97f44cf 📝 Update release notes 2020-07-22 08:47:48 +02:00
Sebastián Ramírez
f64c448329 🔖 Release version 0.60.1 2020-07-22 08:44:44 +02:00
Sebastián Ramírez
df6cbc5ec6 📝 Update release notes 2020-07-22 08:44:13 +02:00
Sebastián Ramírez
0f0af751e4 🔊 Add debugging logs for GitHub actions to introspect GitHub hidden context (#1764) 2020-07-22 08:43:26 +02:00
Sebastián Ramírez
6c9dca55bc 📝 Update release notes 2020-07-22 08:32:22 +02:00
Adrien Cacciaguerra
d71e807401 💄 Use OS preference theme for docs (#1760) 2020-07-22 08:30:12 +02:00
Sebastián Ramírez
7df9ddfe4e 📝 Update release notes 2020-07-22 08:28:31 +02:00
James Alford-Golojuch
4170659359 ⬆ Updates Starlette to version 0.13.6 (#1759)
Co-authored-by: jalfordgolojuch <jalfordgolojuch@activecampaign.com>
2020-07-22 08:25:32 +02:00
Sebastián Ramírez
2940a7fdfa 📝 Update release notes 2020-07-22 08:23:36 +02:00
Sebastián Ramírez
dadd6650ed 📌 Pin Swagger UI temporarily 2020-07-22 08:19:26 +02:00
Sebastián Ramírez
c5a21354af 📝 Update release notes 2020-07-21 23:10:52 +02:00
Sebastián Ramírez
8bafe2a482 🚀 GitHub Actions update, use commit from PR, not pre-merge (#1761)
* 🔥 Remove deploy badge that won't show correctly until next release

after the fixes to the Gitter bot

* 🐛 Fix GitHub Action to upload docs artifacts with commit from PR, not pre-merge

* ♻️ Run zip docs and artifact upload only on PRs
2020-07-21 23:08:14 +02:00
Sebastián Ramírez
42f1716b48 📝 Update release notes 2020-07-20 18:57:01 +02:00
Sebastián Ramírez
6ab2841dbb ♻ Update GitHub actions (#1746)
* 🐛 Fix Gitter notification, use development gitter room until next release

* 🔥 Remove trigger docs preview step from build-docs workflow

as it requires a more privileged token, so it's now triggered by the preview docs watcher

* 🔊 Dump context when building to allow debugging how to refactor the Gitter bot
2020-07-20 18:56:13 +02:00
Sebastián Ramírez
0f54657377 🔖 Release version 0.60.0 2020-07-20 18:26:56 +02:00
Sebastián Ramírez
79e5b36551 📝 Update release notes (#1745)
* 📝 Update release notes

* 📝 Update release notes
2020-07-20 18:22:29 +02:00
Sebastián Ramírez
074868d77e Run watch docs previews every hour 2020-07-20 17:55:02 +02:00
Sebastián Ramírez
3dd16a9458 Fetch artifacts only once in preview docs GitHub action 2020-07-20 17:48:43 +02:00
Sebastián Ramírez
62c23ab5fa 🔒 Use personal access token to trigger docs previews 2020-07-20 17:45:28 +02:00
Sebastián Ramírez
11c05beece 🔊 Add more logging to Watch Preview when artifact is not found 2020-07-20 17:13:27 +02:00
Sebastián Ramírez
7b3ef43127 🐛 Fix Watch Preview Docs GitHub Action, strike 2 2020-07-20 16:59:09 +02:00
Sebastián Ramírez
e0080e5f75 🐛 Fix Watch Previews action 2020-07-20 16:47:48 +02:00
Sebastián Ramírez
e1ba54bd12 🔧 Update Watch Docs Previews GitHub action 2020-07-20 16:35:26 +02:00
Sebastián Ramírez
7032dfb4f1 Add GitHub Action to watch for missing preview docs (#1740)
* 📝 Update release notes

* 🔊 Make curl verbose when triggering docs preview

* 🔧 Update GitHub Actions circus to use commit hash

*  Add PR docs preview watcher
2020-07-20 16:33:17 +02:00
Sebastián Ramírez
14e7f7c1f4 ⬆ Upgrade Deploy to Netlify action 2020-07-19 22:27:32 +02:00
Sebastián Ramírez
9ed6f1e419 🐛 Fix custom GitHub action 2020-07-19 22:22:25 +02:00
Sebastián Ramírez
b268c39758 Add internal GitHub action to deploy docs previews (#1739)
* 📝 Update release notes

*  Add internal GitHub action to pull docs artifact

* 🙈 Add archive.zip to gitignore
2020-07-19 22:11:28 +02:00
Sebastián Ramírez
4dd386b807 🚀 Preview docs for external PRs (#1738)
* 🍱 Save docs zip when building docs

* 🙈 Add docs.zip artifact to .gitignore

* 🚀 Update deploy artifact name

* ♻️ Upload artifact directory

*  Add WIP trigger docs preview

* ♻️ Update trigger docs preview

* 👷 Update env vars for docs preview

* 👷 Update PR extraction

* 👷 Try to show GitHub event

* 💚 Try to see if GitHub context templates is causing the problem

* 💚 Try to debug context GitHub event

* 🔊 Debug GitHub event context

* 👷 Update debugging action

* 👷 Update debug

* 👷 Update Action

* ♻️ Update script to trigger docs preview

* ️ Try to use Zip again to improve speed

* 🔧 Update zip scripts

*  Add preview docs on event

* 🚀 Trigger deploy preview on PRs

* 🐛 Fix trigger script env vars
2020-07-19 20:49:52 +02:00
Sebastián Ramírez
b7251f1654 📝 Update release notes 2020-07-19 14:25:28 +02:00
Sebastián Ramírez
780d3e65ad Add XML coverage report for GitHub Actions (#1737) 2020-07-19 14:24:24 +02:00
Sebastián Ramírez
cc8cac200f 📝 Update release notes 2020-07-19 14:10:51 +02:00
Sebastián Ramírez
e7be5c8ac5 💄 Update badges, remove Travis (#1736)
* 💄 Update badges

* 🔥 Remove Travis
2020-07-19 14:09:55 +02:00
Sebastián Ramírez
8f52864899 📝 Update release notes 2020-07-19 14:04:45 +02:00
Sebastián Ramírez
47a630721a 👷 Add GitHub Actions, move from Travis (#1735) 2020-07-19 14:03:38 +02:00
Sebastián Ramírez
10ae6de111 📝 Update release notes 2020-07-19 12:19:39 +02:00
JAYATI SHRIVASTAVA
2b47f3e56b Add support for adding OpenAPI schema for GET requests with a body (#1626)
* add test for get request body's openapi schema

* 📝 Update docs note for GET requests with body

*  Update test for GET request with body, test it receives the body

* 🔇 Temporary type ignore while it's handled in Pydantic

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-07-19 12:17:50 +02:00
Sebastián Ramírez
d60dd1b60e 🔖 Release version 0.59.0 2020-07-10 20:41:35 +02:00
Sebastián Ramírez
2822f7ca64 📝 Update release notes 2020-07-10 20:32:16 +02:00
tomarv2
ff6afeaf78 ✏ Fix docstring typo for oauth2 utils (#1621) 2020-07-10 20:31:15 +02:00
Sebastián Ramírez
74852d406c 📝 Update release notes 2020-07-10 20:26:29 +02:00
Brian Mboya
921642dc7b 📝 Update JWT docs to use python-jose (#1610)
* 📝 Update JWT docs with python-jose

* 📝 Update format and use python-jose in docs

*  Add Python-jose to dependencies

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-07-10 20:24:38 +02:00
Sebastián Ramírez
5c01d44ee9 📝 Update release notes 2020-07-10 19:46:36 +02:00
Sebastián Ramírez
135704dcc8 🐛 Re-enable search bar after adding markdown-data plugin (#1703) 2020-07-10 19:45:47 +02:00
Sebastián Ramírez
88793bb6c2 📝 Update release notes 2020-07-10 19:34:22 +02:00
Rupsi Kaushik
70a51b3aff Auto-generate OpenAPI servers from root_path (#1596)
* root_path included in servers object instead of path prefix

* ♻️ Refactor implementation of auto-including root_path in OpenAPI servers

* 📝 Update docs and examples for Behind a Proxy, including servers

* 📝 Update Extending OpenAPI as openapi_prefix is no longer needed

*  Add extra tests for root_path in servers and root_path_in_servers=False

* 🍱 Update security docs images with relative token URL

* 📝 Update security docs with relative token URL

* 📝 Update example sources with relative token URLs

*  Update tests with relative tokens

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-07-10 19:28:18 +02:00
Sebastián Ramírez
340a582be7 📝 Update release notes 2020-07-10 14:48:42 +02:00
Sebastián Ramírez
5f66b5466f ✏️ Fix external links typo/link (#1702) 2020-07-10 14:47:56 +02:00
Sebastián Ramírez
d2169ee567 📝 Update release notes 2020-07-10 14:35:28 +02:00
Sebastián Ramírez
a5c03ba1b7 External links in docs with data file (#1701)
*  Add mkdocs-markdownextradata-plugin for docs

* 🔧 Update MkDocs config file(s) to include external data

*  Add external links data file

* 📝 Use external data file in External Links

* ♻️ Update data files for langs

The cost is some duplication 😔, these files are updated by the script, but to be able to serve locally they have to be duplicated

*  Update docs script to copy data files

* 🔥 Remove needed duplication of data files for live docs in translations
2020-07-10 14:31:44 +02:00
Sebastián Ramírez
e4ea6426dc 📝 Update release notes 2020-07-10 12:24:03 +02:00
Davide Fiocco
8bf7cd1dc6 📝 Fix link to edit External Links, add additional link (#1669)
Added a link to the correct link to editing the en docs, plus an additional example (of mine!) which got some buzz on social media:
https://twitter.com/monodavide/status/1276913357388382212
https://madewithml.com/projects/1649/model-serving-using-fastapi-and-streamlit/
2020-07-10 12:21:46 +02:00
Sebastián Ramírez
92feb3ade7 📝 Update release notes 2020-07-10 11:18:28 +02:00
Katherine Bancroft
d0e739d8f2 📝 Add note in docs on order in Pydantic Unions (#1591)
* Add note on order in Unions

* Add an example of Union order

Co-authored-by: kbanc <katherine.bancoft@gmail.com>
2020-07-10 11:16:46 +02:00
Sebastián Ramírez
4efa6bd75e 📝 Update release notes 2020-07-10 11:09:43 +02:00
Sebastián Ramírez
600f15faa0 ✔ Improve support for tests in editor (#1699)
* ♻️ Remove required extra steps to test in editor

* 🎨 Format lint script

* 📝 Remove obsolete extra steps required to test in editor from docs

* 🐛 Fix coverage
2020-07-10 11:08:19 +02:00
Sebastián Ramírez
250fa519f9 📝 Update release notes 2020-07-10 00:16:35 +02:00
Sebastián Ramírez
3c6dafcc8e 📌 Pin dependencies (#1697)
* 📌 Pin dependencies

* 🐛 Fix config in pyproject.toml
2020-07-10 00:15:39 +02:00
Sebastián Ramírez
8447000eee 📝 Update release notes 2020-07-09 20:09:38 +02:00
Brian Mboya
fe453f80ed ⬆ Upgrade isort to version 5.x.x (#1670)
* Update isort script to match changes in the new release, isort v5.0.2

* Downgrade isort to version v4.3.21

* Add an alternative flag to --recursive in isort v5.0.2

* Add isort config file

* 🚚 Import from docs_src for tests

* 🎨 Format dependencies.utils

* 🎨 Remove isort combine_as_imports, keep black profile

* 🔧 Update isort config, use pyproject.toml, Black profile

* 🔧 Update format scripts to use explicit directories to format

otherwise it would try to format venv env directories, I have several with different Python versions

* 🎨 Format NoSQL tutorial after re-sorting imports

* 🎨 Fix format for __init__.py

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-07-09 20:06:12 +02:00
Sebastián Ramírez
3ff504f03f 🔖 Release version 0.58.1 2020-06-28 23:48:30 +02:00
Sebastián Ramírez
eea9ab6106 📝 Update release notes 2020-06-28 23:43:30 +02:00
Sebastián Ramírez
e9e07c41bb 🎨 Add format, finishing period 2020-06-28 23:42:32 +02:00
Eyitayo Ogunbiyi
17a5e18f46 📝 Add link to all valid pydantic data types (#1612) 2020-06-28 23:40:45 +02:00
Sebastián Ramírez
9148bd8b6f 📝 Update release notes 2020-06-28 23:38:49 +02:00
Dmytro Petruk
39766d0f96 🐛 Fix link in warning logs (#1611)
Co-authored-by: Dmytro Petruk <petruk@ebu.ch>
2020-06-28 23:37:42 +02:00
Sebastián Ramírez
2d9bca56b2 📝 Update release notes 2020-06-28 23:35:21 +02:00
molto
f158d95ce9 📝 Fix bad link in docs (#1603)
Co-authored-by: lookyun <lookyun0504@outlook.com>
2020-06-28 23:34:28 +02:00
Sebastián Ramírez
7a4164ef60 📝 Update release notes 2020-06-28 23:30:22 +02:00
Brian Mboya
f3730a79af 🙈 Add vim temporary files to gitignore (#1590)
Co-authored-by: asheux <brianashiundu000@gmail.com>
2020-06-28 23:28:35 +02:00
Sebastián Ramírez
42eff23a79 📝 Update release notes 2020-06-28 23:27:40 +02:00
Andreas Schlapbach
25bc33350d ✏ Fix typo in sub-applications (#1578) 2020-06-28 23:26:35 +02:00
Sebastián Ramírez
b84d082005 📝 Update release notes 2020-06-28 20:21:38 +02:00
Sebastián Ramírez
1f01ce9615 📝 Use Optional in docs (#1644)
* Updated .py files with Optional tag (up to body_nested_models)

* Update optionals

* docs_src/ all updates, few I was unsure of

* Updated markdown files with Optional param

* es: Add Optional typing to index.md

* Last of markdown files updated with Optional param

* Update highlight lines

* it: Add Optional typings

* README.md: Update with Optional typings

* Update more highlight increments

* Update highlights

* schema-extra-example.md: Update highlights

* updating highlighting on website to reflect .py changes

* Update highlighting for query-params & response-directly

* Address PR comments

* Get rid of unnecessary comment

*  Revert Optional in Chinese docs as it probably also requires changes in text

* 🎨 Apply format

*  Revert modified example

* ♻️ Simplify example in docs

* 📝 Update OpenAPI callback example to use Optional

*  Add Optional types to tests

* 📝 Update docs about query params, default to using Optional

* 🎨 Update code examples line highlighting

* 📝 Update nested models docs to use "type parameters" instead of "subtypes"

* 📝 Add notes about FastAPI usage of None

including:

= None

and

= Query(None)

and clarify relationship with Optional[str]

* 📝 Add note about response_model_by_alias

* ♻️ Simplify query param list example

* 🔥 Remove test for removed example

*  Update test for updated example

Co-authored-by: Christopher Nguyen <chrisngyn99@gmail.com>
Co-authored-by: yk396 <yk396@cornell.edu>
Co-authored-by: Kai Chen <kaichen120@gmail.com>
2020-06-28 20:13:30 +02:00
Sebastián Ramírez
352c5f5ecc 📝 Update release notes 2020-06-28 13:59:20 +02:00
Sebastián Ramírez
e5594e860f Update response_model_by_alias (#1642)
* Make openapi models honor response_model_by_alias

* Add test for response_model_by_alias working with openapi models

*  Revert changes

*  Update and extend tests for response_model_by_alias

*  Revert test name change

* 📌 Pin Pytest and Pytest-Cov

Co-authored-by: Martin Zaťko <martin.zatko@kiwi.com>
2020-06-28 13:58:21 +02:00
Sebastián Ramírez
50926faead 📝 Update release notes 2020-06-27 20:32:34 +02:00
Sebastián Ramírez
a303afc0e5 📝 Update release notes 2020-06-27 20:32:34 +02:00
Sebastián Ramírez
12607e85e3 📝 Update release notes 2020-06-27 20:32:34 +02:00
Xie Wei
38fd363e89 🌐 Add chinese translation for body-fields.md (#1569)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-06-27 20:29:41 +02:00
Xie Wei
7f62cfd231 🌐 Update Chinese translation for index.md (#1564)
* keep up-to-date with main version

* fix 2 ignored quotes
2020-06-27 20:24:10 +02:00
Xie Wei
c5168bd036 🌐 Add Chinese translation for body-multiple-params.md (#1532)
* add chinese translation for body-multiple-params.md

* improve translations

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-06-27 20:18:10 +02:00
Sebastián Ramírez
be472c5215 📝 Update release notes 2020-06-27 20:13:07 +02:00
Xie Wei
adac38ecea Add Chinese translation for path-params-numeric-validations.md (#1506)
* add chinese translation for path-params-numeric-validations.md

* improve translations
2020-06-27 20:10:32 +02:00
Sebastián Ramírez
c8b634226e 📝 Update release notes 2020-06-27 20:00:21 +02:00
Sebastián Ramírez
ca4cf7cc70 Add GitHub action to label approved PRs (#1638) 2020-06-27 19:59:10 +02:00
Sebastián Ramírez
b87072bc12 🔖 Release version 0.58.0 2020-06-15 13:18:36 +02:00
Sebastián Ramírez
04e2bfafbc 📝 Update release notes 2020-06-15 13:13:53 +02:00
Sebastián Ramírez
181a32236a Deep merge OpenAPI responses (#1577)
* override successful response

*  Add deep_dict_udpate

*  Merge additional responses with generated responses

* 🍱 Update docs screenshot

Co-authored-by: rkbeatss <rkaus053@uottawa.ca>
2020-06-15 13:12:12 +02:00
Sebastián Ramírez
1f54a8e0a1 📝 Update release notes 2020-06-15 12:42:48 +02:00
Andrew
d63475bb7d 📝 Mention in docs that subapps don't fire events (#1554)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-06-14 18:25:10 +02:00
Sebastián Ramírez
5a3c5f1523 📝 Update release notes 2020-06-14 18:12:51 +02:00
Andrew
12bc9285f7 🐛 Fix body validation error response, remove variable name when it is not embedded (#1553) 2020-06-14 18:07:39 +02:00
Sebastián Ramírez
31df2ea940 📝 Update release notes 2020-06-14 17:56:12 +02:00
Sebastián Ramírez
50b90dd6a4 📝 Update release notes 2020-06-14 17:55:13 +02:00
Andrew
7dd881334d 🐛 Fix testing security scopes when using dependency overrides (#1549)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-06-14 17:54:46 +02:00
Vinny Do
530fc8ff3f 🐛 Fix JSON Schema "not" keyword (#1548) 2020-06-14 15:46:49 +02:00
Sebastián Ramírez
ef460b4d23 📝 Update release notes 2020-06-14 15:40:18 +02:00
mikaello
b591de2ace Add support for OpenAPI servers metadata (#1547)
* feat: add servers option for OpenAPI

Closes #872

*  Use dicts for OpenAPI servers

* ♻️ Update OpenAPI Server model to support relative URLs

*  Add tests for OpenAPI servers

* ♻️ Re-order parameter location of servers for OpenAPI

* 🎨 Format code

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-06-14 15:38:29 +02:00
Sebastián Ramírez
34c857b7cb 🔖 Release version 0.57.0 2020-06-13 23:13:25 +02:00
Sebastián Ramírez
c78bc0c82d 📝 Update release notes 2020-06-13 23:08:20 +02:00
JAYATI SHRIVASTAVA
194446e51a 🔥 Remove broken external link (#1565) 2020-06-13 23:07:11 +02:00
Sebastián Ramírez
777e2151e6 📝 Update release notes 2020-06-13 22:55:30 +02:00
Sebastián Ramírez
5ce5bdba0b 📝 Update release notes 2020-06-13 22:52:59 +02:00
Chih Sean Hsu
e4300769ac 📝 Update tutorial for WebSockets with dependencies (#1540)
* fix websockets/tutorial002.py

* fix tutorial002 in ws to correspond with test case

* reformat websocket tutorial002

* fix websocket tutorial002 coverage

* 📝 Update example for WebSockets with Depends

*  Update and refactor tests for WebSockets with dependencies

* 👷 Trigger Travis, as it's not reporting to Codecov

*  Update WebSocket tests to raise coverage

Co-authored-by: Chih Sean Hsu <Sean@Sean-Mac.local>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-06-13 22:51:34 +02:00
retnikt
c6dd627bdd Add support for Python's http.HTTPStatus in status_code (#1534)
* Normalise IntEnums to ints for route status codes

Closes #1349

* add tests for status code enum support

* add docs for status code enum support

* add endpoint test for enum status code

* 📝 Update note about http.HTTPStatus

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-06-13 19:40:10 +02:00
Sebastián Ramírez
6576f724bb 📝 Update release notes 2020-06-13 19:22:08 +02:00
Sebastián Ramírez
91a6736d0e 📝 Update release notes 2020-06-13 19:20:48 +02:00
Patrick Wang
8fb755703d When using Pydantic models with __root__ use the internal value in jsonable_encoder (#1524) 2020-06-13 19:20:11 +02:00
Yankee
748bedd37c 📝 Updated docs for path-params (#1521)
* Added response example; URL for quick access; typo fixes

* Added line breaks for readability

* Fix typo on redoc url

* 📝 Update format, links, rewordings

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-06-13 19:14:23 +02:00
Sebastián Ramírez
bf58788f29 📝 Update release notes 2020-06-13 18:54:47 +02:00
Yankee
5f78ba4a31 📝 Update docs for first-steps, links, rewordings (#1518)
* ✏️ Typo/readability fixes for first-steps documentation

* 📝 Update link and small rewordings

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-06-13 18:53:31 +02:00
Sebastián Ramírez
db9f827263 📝 Update release notes 2020-06-13 18:18:27 +02:00
TiewKH
dd9e94cf21 Enable showCommonExtensions and showExtensions in SwaggerUI (#1466)
* Set showExtensions and showCommonExtensions to true

* Clean up comma

Co-authored-by: tiewkeehui <keehuitiew@airasia.com>
2020-06-13 18:16:34 +02:00
Sebastián Ramírez
e482d74241 📝 Update release notes 2020-06-13 18:13:06 +02:00
Richard Hoekstra
bd2acbcabb Export OAuth2PasswordRequestFormStrict from security (#1462)
* Update __init__.py

Fixes an import error:     

from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestFormStrict
ImportError: cannot import name 'OAuth2PasswordRequestFormStrict'

* Simplify import of OAuth2PasswordRequestFormStrict

* Simplify import of OAuth2PasswordRequestFormStrict
2020-06-13 18:08:08 +02:00
Sebastián Ramírez
f913d469a8 📝 Update release notes 2020-06-13 18:05:22 +02:00
Roman Tezikov
66cb266641 📝 Add docs for default_response_class (#1455)
*  Add docs to default_response_class

*  create a tip

*  fixing the tip

* 🚑 grammar

* 📝 Update docs for default response class

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-06-13 18:02:45 +02:00
Sebastián Ramírez
74954894c5 📝 Update release notes 2020-06-13 15:26:42 +02:00
William Hayes
ceedfccde0 📝 Document additional parameters for response_model (#1427)
* Documented additional parameters

These are included in a recent PR (https://github.com/tiangolo/fastapi/pull/1166) but not in the docs yet.
* response_model_exclude_none
* response_model_exclude_defaults

* 📝 Update note about response_model_exclude_defaults and response_model_exclude_none

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-06-13 15:23:29 +02:00
Sebastián Ramírez
2ee0eedf23 📝 Update release notes 2020-06-13 15:08:10 +02:00
Koudai Aono
c0f3019764 📝 Add PyCharm Pydantic plugin to docs (#1420)
* add pydantic pycharm plugin in document

* 📝 Update PyCharm Pydantic plugin note

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-06-13 15:05:59 +02:00
Sebastián Ramírez
dd6d0cb23c 📝 Update release notes 2020-06-13 14:51:21 +02:00
Chen Rotem Levy
fe15620df3 🎨 Update and clarify testing function name (#1395)
test_create_existing_token -> test_create_existing_item
2020-06-13 14:50:14 +02:00
Sebastián Ramírez
6af857f206 📝 Update release notes 2020-06-13 14:47:03 +02:00
obataku
7ce756f9dd 🐛 Fix duplicated headers set by indirect dependencies (#1386)
* Added test for repeating cookies in response headers

* update `response` headers, status code to match `sub_response` in `solve_dependencies` only if necessary; fix formatting of scottsmith2gmail's test

* restore code coverage, remove dead code from `solve_dependencies`

Co-authored-by: Scott Smith <scott.smith.2@gmail.com>
2020-06-13 14:44:51 +02:00
Sebastián Ramírez
c0b1fddb31 📝 Update release notes 2020-06-13 14:39:58 +02:00
Nick Rushton
9aea85a84e ⬆ Upgrade Starlette dependency to 0.13.4 (#1361) 2020-06-13 14:38:08 +02:00
Sebastián Ramírez
fddd1c12de 📝 Update release notes 2020-06-13 14:36:27 +02:00
Aviram Hassan
b13a4baf32 Add better JSON decode error handling, improve feedback for client after invalid JSON requests (#1354)
* Request body error, raise RequestValidationError instead of HTTPException in case JSON decode failure

* add missing test case for body general exception
2020-06-13 14:33:27 +02:00
Sebastián Ramírez
5ffa18f10f 📝 Update release notes 2020-06-13 14:06:12 +02:00
Sebastián Ramírez
828915baf5 📝 Update Tags metadata title 2020-06-13 14:02:58 +02:00
Thomas Maschler
a071ddf3cd Add support for tag metadata in OpenAPI (#1348)
* Allow to add OpenAPI tag descriptions

* fix type hint

* fix type hint 2

* refactor test to assure 100% coverage

* 📝 Update tags metadata example

* 📝 Update docs for tags metadata

*  Move tags metadata test to tutorial subdir

* 🎨 Update format in applications

* 🍱 Update docs UI image based on new example

* 🎨 Apply formatting after solving conflicts

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-06-13 13:58:06 +02:00
Sebastián Ramírez
3651b8a30f 📝 Update release notes 2020-06-13 12:27:00 +02:00
Sebastián Ramírez
0d73b9ff1c 🔧 Add basic setup for Russian translations (#1566) 2020-06-13 12:26:15 +02:00
Sebastián Ramírez
43235cf236 📝 Update release notes 2020-06-13 09:47:36 +02:00
Xie Wei
269a155583 🔥 Remove obsolete Chinese articles after translations (#1510) 2020-06-13 09:45:48 +02:00
Sebastián Ramírez
12433d51dd 📝 Update release notes 2020-06-13 01:25:29 +02:00
Rupsi Kaushik
3699e17212 Implement __repr__ methods for path parameters to simplify debugging (#1560)
* repr description added to Depends class

* repr description added to Security subclass

* get rid of __repr__ in security since it will inherit from super

* make code format consistent with rest

* add desc for rest of the classes

* Update fastapi/params.py

remove trailing whitespace

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

* Implement __repr__

* fix formatting

* formatting again

* ran formatting

* added basic testing

* basic tests added to rest of the classes

* added more test coverage and simplified test file

Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
Co-authored-by: Jayati Shrivastava <gaurijove@gmail.com>
2020-06-13 01:22:30 +02:00
Sebastián Ramírez
8231fbede4 🔖 Release version 0.56.1 2020-06-13 01:17:06 +02:00
Sebastián Ramírez
50bc14b835 📝 Update release notes 2020-06-13 01:14:58 +02:00
Kai Chen
4310c89c83 📝 Add link to Advanced User Guide: response status code (#1512) 2020-06-13 01:12:59 +02:00
Sebastián Ramírez
d39dd06a22 📝 Update release notes 2020-06-13 00:57:34 +02:00
kota matsuoka
a0ab47e89e 🎨 Remove unused f-string (#1526) 2020-06-13 00:56:00 +02:00
Sebastián Ramírez
5cbcb9a965 📝 Update release notes 2020-06-13 00:55:30 +02:00
Xie Wei
801ceaec80 🌐 Add Chinese translation for query-params-str-validations.md (#1500)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-06-13 00:53:00 +02:00
Sebastián Ramírez
c7334ae9f8 📝 Update release notes 2020-06-13 00:50:22 +02:00
Xie Wei
d737599a2c 🌐 Add Chinese translation for body.md (#1492)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-06-13 00:47:50 +02:00
Sebastián Ramírez
d2d72a8e4a 📝 Update release notes 2020-06-13 00:43:07 +02:00
Xie Wei
7895c12fa1 🌐 Add Chinese translation for help-fastapi.md (#1465)
* add chinese translation for help-fastapi.md

* improve translations

Co-authored-by: Waynerv <wei.xie@woqutech.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-06-13 00:40:05 +02:00
Sebastián Ramírez
5f6a14c413 📝 Update release notes 2020-06-13 00:29:43 +02:00
Xie Wei
2b4e88fa98 🌐 Add Chinese translation for query-params.md (#1454)
Co-authored-by: Waynerv <wei.xie@woqutech.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-06-13 00:26:40 +02:00
Sebastián Ramírez
11723bca27 📝 Update release notes 2020-06-13 00:21:53 +02:00
Xie Wei
b49517a64f 🌐 Add Chinese translation for contributing.md (#1460)
Co-authored-by: Waynerv <wei.xie@woqutech.com>
2020-06-13 00:18:57 +02:00
Sebastián Ramírez
f910e0c96c 📝 Update release notes 2020-06-13 00:18:20 +02:00
Xie Wei
c1ba2a3127 🌐 Add Chinese translation for path-params.md (#1453)
* add chinese translation for path-params.md

* improve translations

* improve translations

Co-authored-by: Waynerv <wei.xie@woqutech.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-06-13 00:14:58 +02:00
Sebastián Ramírez
28396173c7 📝 Update release notes 2020-06-13 00:09:41 +02:00
Kabir Khan
69974b792e 📝 Add cookiecutter-spacy-fastapi to docs (#1390) 2020-06-13 00:06:53 +02:00
Sebastián Ramírez
352412a3cb 📝 Update release notes 2020-06-12 23:46:05 +02:00
yaegassy
745ab48d65 📝 Add docs in Python Types for Optional (#1377)
* docs: Fix pydantic example in python-types.md

* 📝 Update Python Types Intro to include Optional

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-06-12 23:44:23 +02:00
Sebastián Ramírez
4a5cda0d77 📝 Update release notes 2020-06-12 23:00:09 +02:00
Micah Rosales
b90bf2da9e 🐛 Fix callable class generator dependencies (#1365)
* Fix callable class generator dependencies

* workaround to support asynccontextmanager backfill for pre python3.7

Co-authored-by: Micah Rosales <mrosales@users.noreply.github.com>
2020-06-12 22:57:59 +02:00
Sebastián Ramírez
a552cbdf59 📝 Update release notes 2020-06-12 22:47:37 +02:00
Dylan Anthony
2351fb5623 🔇 Remove error log when parsing malformed JSON body as it's a client error (#1351) 2020-06-12 22:44:40 +02:00
Sebastián Ramírez
807522c616 📝 Update release notes 2020-06-12 22:42:40 +02:00
Xie Wei
81a529c251 🌐 Translate doc first steps to Chinese (#1323)
* WIP:add Chinese translation for first steps doc

* add Chinese translation for first steps doc

* improve translations

Co-authored-by: Waynerv <wei.xie@woqutech.com>
2020-06-12 22:39:26 +02:00
Sebastián Ramírez
7efc15aeef 📝 Update release notes 2020-06-12 22:37:34 +02:00
Nik
d66d8379c0 🐛 Fix OpenAPI generation when using callbacks with routers including Pydantic models (#1322)
* drop model class from additional responses when generating openapi

* ♻️ Copy response to be mutated early in get_openapi_path

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-06-12 22:35:59 +02:00
Sebastián Ramírez
5a00467951 📝 Update release notes 2020-06-12 22:01:22 +02:00
Kazantcev Andrey
434d32b891 Optimize regexp pattern in get_path_param_names (#1243) 2020-06-12 21:59:32 +02:00
Sebastián Ramírez
535247ffc4 📝 Update release notes 2020-06-12 21:43:17 +02:00
Pankaj Giri
7e2518350a 📝 Remove *, from functions where it's not needed #1234 (#1239)
* Fix for - [FEATURE] Remove *, where it's not needed #1234

* 🔥 Remove unnecessary arg *,

* 🎨 Update docs format highlight lines

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-06-12 21:41:44 +02:00
Sebastián Ramírez
1b2a7546af 📝 Update release notes 2020-06-12 18:58:15 +02:00
Cesare De Cal
2d9bb64047 🌐 Generated new translation directory to support Italian docs (#1557)
* Generated new translation directory to support Italian docs

* ⬆️ Upgrade/pin pytest to >= 5.4.3

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-06-12 18:53:52 +02:00
Sebastián Ramírez
072c2bc7f9 🔖 Release version 0.56.0 2020-06-12 00:22:17 +02:00
Sebastián Ramírez
da7826b0eb 📝 Update release notes 2020-06-12 00:05:17 +02:00
Ingmar Steen
2f478eeca6 Add support for ASGI root_path for openapi docs (#1199)
* Use ASGI root_path when it is provided and openapi_prefix is empty.

* Strip trailing slashes from root_path.

* Please mypy.

* Fix extending openapi test.

* 📝 Add docs and tutorial for using root_path behind a proxy

* ♻️ Refactor application root_path logic, use root_path, deprecate openapi_prefix

*  Add tests for Behind a Proxy with root_path

* ♻️ Refactor test

* 📝 Update/add docs for Sub-applications and Behind a Proxy

* 📝 Update Extending OpenAPI with openapi_prefix parameter

*  Add test for deprecated openapi_prefix

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-06-11 23:53:19 +02:00
Sebastián Ramírez
543ef7753a 📝 Update release notes 2020-06-07 22:02:36 +02:00
Sebastián Ramírez
88a887329e 📝 Update help and issue templates (#1531)
* 📝 Update help docs: Gitter, issues, links

also fix Gitter tab padding

* 📝 Update new GitHub issue templates

* 📝 Add note about extra help required for new issues
2020-06-07 22:00:15 +02:00
Sebastián Ramírez
8cfe254400 📝 Update release notes 2020-06-05 17:35:39 +02:00
Sebastián Ramírez
bfd46e562b 🔧 Update issue-manager GitHub action (#1520) 2020-06-05 17:34:43 +02:00
Sebastián Ramírez
a0e4d38bea 📝 Update release notes 2020-05-24 08:48:52 +02:00
Sebastián Ramírez
b0414b9929 📝 Add new links (#1467)
* 📝 Update opinions including Netflix and add format

* 📝 Add new external links

* 📝 Update README
2020-05-24 08:48:09 +02:00
Sebastián Ramírez
3b4413f9f5 📝 Update release notes 2020-05-24 07:47:19 +02:00
Xie Wei
374cdf29a9 🌐 Add Chinese translation for docs/python-types.md (#1197)
* Add Chinese tranlation for docs/python-types.md

* improve translation
2020-05-24 07:43:26 +02:00
Sebastián Ramírez
8d844bc5cf 🔖 Release version 0.55.1 2020-05-23 18:59:14 +02:00
Sebastián Ramírez
1092261ae1 📝 Update release notes 2020-05-23 18:59:14 +02:00
Sebastián Ramírez
5984233223 🐛 Fix Enum handling with their own schema definitions (#1463)
* 🐛 Fix extra support for enum with its own schema

*  Fix/update test for enum with its own schema

* 🐛 Fix type declarations

* 🔧 Update format and lint scripts to support locally installed Pydantic and Starlette

* 🐛 Add temporary type ignores while enum schemas are merged
2020-05-23 18:56:18 +02:00
Sebastián Ramírez
98bb9f13da 🔖 Release version 0.55.0 2020-05-23 16:06:32 +02:00
Sebastián Ramírez
d375dc6ebe 📝 Update release notes 2020-05-23 16:06:32 +02:00
Sebastián Ramírez
ee335bca82 Add test to support Enums with their own re-usable schema (#1461) 2020-05-23 16:04:25 +02:00
Sebastián Ramírez
601d8eb809 📝 Update release notes 2020-05-17 16:04:35 +02:00
Sebastián Ramírez
b99f350a18 📝 Add links to GitHub sponsors 💸 (#1425)
* 📝 Add links to GitHub sponsors

* ✏ Update link to sponsors
2020-05-17 16:03:53 +02:00
Sebastián Ramírez
c1b0e796c6 📝 Update release notes 2020-05-17 13:51:46 +02:00
retnikt
d9e65147c7 ✏ Fix minor erratum in Question issue template (#1344) 2020-05-17 13:50:42 +02:00
Sebastián Ramírez
6001513c4f 📝 Update release notes 2020-05-17 13:50:05 +02:00
Stavros Korokithakis
3fa033d8d5 📝 Add warning about storing user passwords (#1336) 2020-05-17 13:48:05 +02:00
Sebastián Ramírez
59f7e66ac3 📝 Update release notes 2020-05-17 13:41:12 +02:00
Chen Rotem Levy
08e8dfccbe ✏️ Fix typo in [en] tutorial: exception handeling (#1326)
* Fix typo

* ✏️ Fix typo

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-05-17 13:40:55 +02:00
Sebastián Ramírez
fc70a2f36f 📝 Update release notes 2020-05-17 13:36:04 +02:00
Fabio Serrao
f5c5dbb739 🌐 Add Portuguese translation for alternatives.md (#1325)
* Portuguese translation for alternatives.md

* 🔥 Remove file not yet translated

* ✏️ Add small format and wording changes

* 🔧 Update Portuguese MkDocs

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-05-17 13:32:44 +02:00
Sebastián Ramírez
ca939fabf7 📝 Update release notes 2020-05-17 12:59:17 +02:00
Xie Wei
cc3d795bea ✏ Fix 2 typos in docs (#1324) 2020-05-17 12:56:57 +02:00
Sebastián Ramírez
7fc1bac54b 📝 Update release notes 2020-05-17 12:50:00 +02:00
Sebastián Ramírez
27367df90c 📝 Update release notes 2020-05-17 12:49:02 +02:00
Derek Bekoe
f93861e321 📝 Update cors.md - CORS max_age 600 (#1301)
Update max_age documentation from 60 to the actual default value of 600.
https://github.com/encode/starlette/blob/master/starlette/middleware/cors.py#L23

Related PR https://github.com/encode/starlette/pull/909
2020-05-17 12:48:02 +02:00
Fabio Serrao
30e56ec835 🌐 Add Portuguese translation for index.md (#1300)
* Portuguese Translation for index.md

* ✏️ Update * for consistency with recent changes

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-05-17 12:46:22 +02:00
Sebastián Ramírez
48ccef9ad2 📝 Update release notes 2020-05-17 12:38:10 +02:00
Chris Allnutt
b79e002635 ✏ Re-word and clarify docs for extra info in body-fields (#1299)
* Fixed Typo in [EN] tutorial: body-fields
- remove duplicate of examples text

* ✏️ Re-word and clarify extra info docs

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-05-17 12:37:15 +02:00
Sebastián Ramírez
1fa28b7cb6 📝 Update release notes 2020-05-17 12:30:00 +02:00
Sebastián Ramírez
22f7eae3f2 ✏️ Make sure the * in the README is consistent in the docs (#1424) 2020-05-17 12:28:37 +02:00
Sebastián Ramírez
ae93773465 📝 Update release notes 2020-05-17 12:15:58 +02:00
Sebastián Ramírez
0f387553d1 📝 Update release notes 2020-05-17 12:15:08 +02:00
Beau Barker
d53a253c8d 📝 Update location of get_db in SQL docs (#1293) 2020-05-17 12:14:14 +02:00
Sebastián Ramírez
f8f0a6e462 ✏️ Fix typos in async docs (#1423) 2020-05-17 12:11:17 +02:00
475 changed files with 19483 additions and 3192 deletions

1
.env
View File

@@ -1 +0,0 @@
PYTHONPATH=./docs_src

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

1
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1 @@
github: [tiangolo]

View File

@@ -1,62 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: "[BUG]"
labels: bug
assignees: ''
---
### Describe the bug
Write here a clear and concise description of what the bug is.
### To Reproduce
Steps to reproduce the behavior with a minimum self-contained file.
Replace each part with your own scenario:
1. Create a file with:
```Python
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
```
3. Open the browser and call the endpoint `/`.
4. It returns a JSON with `{"Hello": "World"}`.
5. But I expected it to return `{"Hello": "Sara"}`.
### Expected behavior
Add a clear and concise description of what you expected to happen.
### Screenshots
If applicable, add screenshots to help explain your problem.
### Environment
- OS: [e.g. Linux / Windows / macOS]
- FastAPI Version [e.g. 0.3.0], get it with:
```bash
python -c "import fastapi; print(fastapi.__version__)"
```
- Python version, get it with:
```bash
python --version
```
### Additional context
Add any other context about the problem here.

View File

@@ -1,26 +1,104 @@
---
name: Feature request
about: Suggest an idea for this project
title: "[FEATURE]"
title: ""
labels: enhancement
assignees: ''
---
### Is your feature request related to a problem
### First check
Is your feature request related to a problem?
* [ ] I added a very descriptive title to this issue.
* [ ] I used the GitHub search to find a similar issue and didn't find it.
* [ ] I searched the FastAPI documentation, with the integrated search.
* [ ] I already searched in Google "How to X in FastAPI" and didn't find any information.
* [ ] I already read and followed all the tutorial in the docs and didn't find an answer.
* [ ] I already checked if it is not related to FastAPI but to [Pydantic](https://github.com/samuelcolvin/pydantic).
* [ ] I already checked if it is not related to FastAPI but to [Swagger UI](https://github.com/swagger-api/swagger-ui).
* [ ] I already checked if it is not related to FastAPI but to [ReDoc](https://github.com/Redocly/redoc).
* [ ] After submitting this, I commit to:
* Read open issues with questions until I find 2 issues where I can help someone and add a comment to help there.
* Or, I already hit the "watch" button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.
* Implement a Pull Request for a confirmed bug.
Add a clear and concise description of what the problem is. Ex. I want to be able to [...] but I can't because [...]
<!--
I'm asking all this because answering questions and solving problems in GitHub issues consumes a lot of time. I end up not being able to add new features, fix bugs, review Pull Requests, etc. as fast as I wish because I have to spend too much time handling issues.
All that, on top of all the incredible help provided by a bunch of community members that give a lot of their time to come here and help others.
That's a lot of work they are doing, but if more FastAPI users came to help others like them just a little bit more, it would be much less effort for them (and you and me 😅).
-->
### Example
Here's a self-contained [minimal, reproducible, example](https://stackoverflow.com/help/minimal-reproducible-example) with my use case:
<!-- Replace the code below with your own self-contained, minimal, reproducible, example -->
```Python
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
```
### Description
<!-- Replace the content below with your own feature request -->
* Open the browser and call the endpoint `/`.
* It returns a JSON with `{"Hello": "World"}`.
* I would like it to have an extra parameter to teleport me to the moon and back.
### The solution you would like
Add a clear and concise description of what you want to happen.
<!-- Replace this with your own content -->
I would like it to have a `teleport_to_moon` parameter that defaults to `False`, and can be set to `True` to teleport me:
```Python
from fastapi import FastAPI
app = FastAPI()
@app.get("/", teleport_to_moon=True)
def read_root():
return {"Hello": "World"}
```
### Describe alternatives you've considered
Add a clear and concise description of any alternative solutions or features you've considered.
<!-- Replace this with your own ideas -->
To wait for Space X moon travel plans to drop down long after they release them. But I would rather teleport.
### Environment
* OS: [e.g. Linux / Windows / macOS]:
* FastAPI Version [e.g. 0.3.0]:
To know the FastAPI version use:
```bash
python -c "import fastapi; print(fastapi.__version__)"
```
* Python version:
To know the Python version use:
```bash
python --version
```
### Additional context
Add any other context or screenshots about the feature request here.
<!-- Add any other context or screenshots about the question here. -->

View File

@@ -1,24 +1,81 @@
---
name: Question
about: Ask a question
title: "[QUESTION]"
name: Question or Problem
about: Ask a question or ask about a problem
title: ""
labels: question
assignees: ''
assignees: ""
---
### First check
* [ ] I added a very descriptive title to this issue.
* [ ] I used the GitHub search to find a similar issue and didn't find it.
* [ ] I searched the FastAPI documentation, with the integrated search.
* [ ] I already searched in Google "How to X in FastAPI" and didn't find any information.
* [ ] I already read and followed all the tutorial in the docs and didn't find an answer.
* [ ] I already checked if it is not related to FastAPI but to [Pydantic](https://github.com/samuelcolvin/pydantic).
* [ ] I already checked if it is not related to FastAPI but to [Swagger UI](https://github.com/swagger-api/swagger-ui).
* [ ] I already checked if it is not related to FastAPI but to [ReDoc](https://github.com/Redocly/redoc).
* [ ] After submitting this, I commit to one of:
* Read open issues with questions until I find 2 issues where I can help someone and add a comment to help there.
* I already hit the "watch" button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.
* Implement a Pull Request for a confirmed bug.
<!--
I'm asking all this because answering questions and solving problems in GitHub issues consumes a lot of time. I end up not being able to add new features, fix bugs, review Pull Requests, etc. as fast as I wish because I have to spend too much time handling issues.
All that, on top of all the incredible help provided by a bunch of community members that give a lot of their time to come here and help others.
That's a lot of work they are doing, but if more FastAPI users came to help others like them just a little bit more, it would be much less effort for them (and you and me 😅).
-->
### Example
Here's a self-contained, [minimal, reproducible, example](https://stackoverflow.com/help/minimal-reproducible-example) with my use case:
<!-- Replace the code below with your own self-contained, minimal, reproducible, example, if I (or someone) can copy it, run it, and see it right away, there's a much higher chance I (or someone) will be able to help you -->
```Python
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
```
### Description
How can I [...]?
<!-- Replace the content below with your own problem, question, or error -->
Is it possible to [...]?
* Open the browser and call the endpoint `/`.
* It returns a JSON with `{"Hello": "World"}`.
* But I expected it to return `{"Hello": "Sara"}`.
### Environment
* OS: [e.g. Linux / Windows / macOS]:
* FastAPI Version [e.g. 0.3.0]:
To know the FastAPI version use:
```bash
python -c "import fastapi; print(fastapi.__version__)"
```
* Python version:
To know the Python version use:
```bash
python --version
```
### Additional context
Add any other context or screenshots about the feature request here.
<!-- Add any other context or screenshots about the question here. -->

View File

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

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")

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

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

View File

@@ -0,0 +1,10 @@
name: "Watch docs previews in PRs"
description: "Check PRs and trigger new docs deploys"
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
runs:
using: 'docker'
image: 'Dockerfile'

View File

@@ -0,0 +1,101 @@
import logging
from datetime import datetime
from pathlib import Path
from typing import List, Optional
import httpx
from github import Github
from github.NamedUser import NamedUser
from pydantic import BaseModel, BaseSettings, SecretStr
github_api = "https://api.github.com"
netlify_api = "https://api.netlify.com"
class Settings(BaseSettings):
input_token: SecretStr
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]
def get_message(commit: str) -> str:
return f"Docs preview for commit {commit} at"
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)
owner: NamedUser = repo.owner
headers = {"Authorization": f"token {settings.input_token.get_secret_value()}"}
prs = list(repo.get_pulls(state="open"))
response = httpx.get(
f"{github_api}/repos/{settings.github_repository}/actions/artifacts",
headers=headers,
)
data = response.json()
artifacts_response = ArtifactResponse.parse_obj(data)
for pr in prs:
logging.info("-----")
logging.info(f"Processing PR #{pr.number}: {pr.title}")
pr_comments = list(pr.get_issue_comments())
pr_commits = list(pr.get_commits())
last_commit = pr_commits[0]
for pr_commit in pr_commits:
if pr_commit.commit.author.date > last_commit.commit.author.date:
last_commit = pr_commit
commit = last_commit.commit.sha
logging.info(f"Last commit: {commit}")
message = get_message(commit)
notified = False
for pr_comment in pr_comments:
if message in pr_comment.body:
notified = True
logging.info(f"Docs preview was notified: {notified}")
if not notified:
artifact_name = f"docs-zip-{commit}"
use_artifact: Optional[Artifact] = None
for artifact in artifacts_response.artifacts:
if artifact.name == artifact_name:
use_artifact = artifact
break
if not use_artifact:
logging.info("Artifact not available")
else:
logging.info(f"Existing artifact: {use_artifact.name}")
response = httpx.post(
"https://api.github.com/repos/tiangolo/fastapi/actions/workflows/preview-docs.yml/dispatches",
headers=headers,
json={
"ref": "master",
"inputs": {
"pr": f"{pr.number}",
"name": artifact_name,
"commit": commit,
},
},
)
logging.info(
f"Trigger sent, response status: {response.status_code} - content: {response.content}"
)
logging.info("Finished")

View File

@@ -1,4 +1,4 @@
name: Build and Deploy to Netlify
name: Build Docs
on:
push:
pull_request:
@@ -7,6 +7,10 @@ jobs:
build:
runs-on: ubuntu-18.04
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v1
@@ -18,12 +22,19 @@ jobs:
run: python3.7 -m flit install --extras doc
- name: Build Docs
run: python3.7 ./scripts/docs.py build-all
- name: Zip docs
run: bash ./scripts/zip-docs.sh
- uses: actions/upload-artifact@v2
with:
name: docs-zip
path: ./docs.zip
- name: Deploy to Netlify
uses: nwtgck/actions-netlify@v1.0.3
uses: nwtgck/actions-netlify@v1.1.5
with:
publish-dir: './site'
production-branch: master
github-token: ${{ secrets.GITHUB_TOKEN }}
enable-commit-comment: false
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}

View File

@@ -1,15 +1,24 @@
name: Issue Manager
on:
schedule:
- cron: "0 0 * * *"
- cron: "0 0 * * *"
issue_comment:
types:
- created
- edited
issues:
types:
- labeled
jobs:
issue-manager:
runs-on: ubuntu-latest
steps:
- uses: tiangolo/issue-manager@master
with:
token: ${{ secrets.GITHUB_TOKEN }}
config: >
- uses: tiangolo/issue-manager@0.2.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
config: >
{
"answered": {
"users": ["tiangolo", "dmontagu"],

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 }}

41
.github/workflows/preview-docs.yml vendored Normal file
View File

@@ -0,0 +1,41 @@
name: Preview Docs
on:
workflow_run:
workflows:
- Build Docs
types:
- completed
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Download Artifact Docs
uses: dawidd6/action-download-artifact@v2.9.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
workflow: build-docs.yml
run_id: ${{ github.event.workflow_run.id }}
name: docs-zip
- name: Unzip docs
run: |
rm -rf ./site
unzip docs.zip
rm -f docs.zip
- name: Deploy to Netlify
id: netlify
uses: nwtgck/actions-netlify@v1.1.5
with:
publish-dir: './site'
production-deploy: false
github-token: ${{ secrets.GITHUB_TOKEN }}
enable-commit-comment: false
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
- name: Comment Deploy
uses: ./.github/actions/comment-docs-preview-in-pr
with:
token: ${{ secrets.GITHUB_TOKEN }}
deploy_url: "${{ steps.netlify.outputs.deploy-url }}"

39
.github/workflows/publish.yml vendored Normal file
View File

@@ -0,0 +1,39 @@
name: Publish
on:
release:
types:
- created
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: "3.6"
- name: Install Flit
run: pip install flit
- name: Install Dependencies
run: flit install --symlink
- name: Publish
env:
FLIT_USERNAME: ${{ secrets.FLIT_USERNAME }}
FLIT_PASSWORD: ${{ secrets.FLIT_PASSWORD }}
run: bash scripts/publish.sh
- name: Dump GitHub context
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

29
.github/workflows/test.yml vendored Normal file
View File

@@ -0,0 +1,29 @@
name: Test
on:
push:
pull_request:
types: [opened, synchronize]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.6, 3.7, 3.8]
fail-fast: false
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python-version }}
- name: Install Flit
run: pip install flit
- name: Install Dependencies
run: flit install --symlink
- name: Test
run: bash scripts/test.sh
- name: Upload coverage
uses: codecov/codecov-action@v1

7
.gitignore vendored
View File

@@ -16,3 +16,10 @@ Pipfile.lock
env3.*
env
docs_build
venv
docs.zip
archive.zip
# vim temporary files
*~
.*.sw?

View File

@@ -1,32 +0,0 @@
dist: xenial
language: python
cache: pip
python:
- "3.6"
- "3.7"
- "3.8"
- "nightly"
matrix:
allow_failures:
- python: "nightly"
install:
- pip install flit
- flit install --symlink
script:
- bash scripts/test.sh
after_script:
- bash <(curl -s https://codecov.io/bash)
deploy:
provider: script
script: bash scripts/deploy.sh
on:
tags: true
python: "3.6"

View File

@@ -5,14 +5,14 @@
<em>FastAPI framework, high performance, easy to learn, fast to code, ready for production</em>
</p>
<p align="center">
<a href="https://travis-ci.com/tiangolo/fastapi" target="_blank">
<img src="https://travis-ci.com/tiangolo/fastapi.svg?branch=master" alt="Build Status">
<a href="https://github.com/tiangolo/fastapi/actions?query=workflow%3ATest" target="_blank">
<img src="https://github.com/tiangolo/fastapi/workflows/Test/badge.svg" alt="Test">
</a>
<a href="https://codecov.io/gh/tiangolo/fastapi" target="_blank">
<img src="https://img.shields.io/codecov/c/github/tiangolo/fastapi" alt="Coverage">
<img src="https://img.shields.io/codecov/c/github/tiangolo/fastapi?color=%2334D058" alt="Coverage">
</a>
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://badge.fury.io/py/fastapi.svg" alt="Package version">
<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">
@@ -33,50 +33,66 @@ The key features are:
* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
* **Fast to code**: Increase the speed to develop features by about 200% to 300% *.
* **Fast to code**: Increase the speed to develop features by about 200% to 300%. *
* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. *
* **Intuitive**: Great editor support. <abbr title="also known as auto-complete, autocompletion, IntelliSense">Completion</abbr> everywhere. Less time debugging.
* **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.*"
"_[...] 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._"
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/tiangolo/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div>
---
"*Im over the moon excited about **FastAPI**. Its so fun!*"
"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_"
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div>
---
"_**Netflix** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_"
<div style="text-align: right; margin-right: 10%;">Kevin Glisson, Marc Vilanova, Forest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072" target="_blank"><small>(ref)</small></a></div>
---
"_Im over the moon excited about **FastAPI**. Its so fun!_"
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a> podcast host</strong> <a href="https://twitter.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
---
"*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.*"
"_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>
---
"*If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]*"
"_If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]_"
"*We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]*"
"_We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]_"
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> founders - <a href="https://spacy.io" target="_blank">spaCy</a> creators</strong> <a href="https://twitter.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://twitter.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
---
"*We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]*"
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div>
---
## **Typer**, the FastAPI of CLIs
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
@@ -106,7 +122,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">
@@ -125,6 +141,8 @@ $ pip install uvicorn
* Create a file `main.py` with:
```Python
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@@ -136,7 +154,7 @@ def read_root():
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "q": q}
```
@@ -145,7 +163,9 @@ def read_item(item_id: int, q: str = None):
If your code uses `async` / `await`, use `async def`:
```Python hl_lines="7 12"
```Python hl_lines="9 14"
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@@ -157,7 +177,7 @@ async def read_root():
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str = None):
async def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "q": q}
```
@@ -235,7 +255,9 @@ 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="2 7 8 9 10 23 24 25"
```Python hl_lines="4 9-12 25-27"
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
@@ -245,7 +267,7 @@ app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: bool = None
is_offer: Optional[bool] = None
@app.get("/")
@@ -254,7 +276,7 @@ def read_root():
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "q": q}
@@ -416,9 +438,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).
@@ -427,7 +449,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

@@ -0,0 +1,238 @@
articles:
english:
- link: https://medium.com/@williamhayes/fastapi-starlette-debug-vs-prod-5f7561db3a59
title: FastAPI/Starlette debug vs prod
author_link: https://medium.com/@williamhayes
author: William Hayes
- link: https://medium.com/data-rebels/fastapi-google-as-an-external-authentication-provider-3a527672cf33
title: FastAPIGoogle as an external authentication provider
author_link: https://medium.com/@nilsdebruin
author: Nils de Bruin
- link: https://medium.com/data-rebels/fastapi-how-to-add-basic-and-cookie-authentication-a45c85ef47d3
title: FastAPIHow to add basic and cookie authentication
author_link: https://medium.com/@nilsdebruin
author: Nils de Bruin
- link: https://dev.to/errietta/introduction-to-the-fastapi-python-framework-2n10
title: Introduction to the fastapi python framework
author_link: https://dev.to/errietta
author: Errieta Kostala
- link: https://nickc1.github.io/api,/scikit-learn/2019/01/10/scikit-fastapi.html
title: "FastAPI and Scikit-Learn: Easily Deploy Models"
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"
author_link: https://medium.com/@nilsdebruin
author: Nils de Bruin
- link: https://medium.com/@nico.axtmann95/deploying-a-scikit-learn-model-with-onnx-und-fastapi-1af398268915
title: Deploying a scikit-learn model with ONNX and FastAPI
author_link: https://www.linkedin.com/in/nico-axtmann
author: Nico Axtmann
- link: https://geekflare.com/python-asynchronous-web-frameworks/
title: Top 5 Asynchronous Web Frameworks for Python
author_link: https://geekflare.com/author/ankush/
author: Ankush Thakur
- link: https://medium.com/@gntrm/jwt-authentication-with-fastapi-and-aws-cognito-1333f7f2729e
title: JWT Authentication with FastAPI and AWS Cognito
author_link: https://twitter.com/gntrm
author: Johannes Gontrum
- link: https://towardsdatascience.com/how-to-deploy-a-machine-learning-model-dc51200fe8cf
title: How to Deploy a Machine Learning Model
author_link: https://www.linkedin.com/in/mgrootendorst/
author: Maarten Grootendorst
- link: https://eng.uber.com/ludwig-v0-2/
title: "Uber: Ludwig v0.2 Adds New Features and Other Improvements to its Deep Learning Toolbox [including a FastAPI server]"
author_link: https://eng.uber.com
author: Uber Engineering
- link: https://gitlab.com/euri10/fastapi_cheatsheet
title: A FastAPI and Swagger UI visual cheatsheet
author_link: https://gitlab.com/euri10
author: "@euri10"
- link: https://medium.com/@mike.p.moritz/using-docker-compose-to-deploy-a-lightweight-python-rest-api-with-a-job-queue-37e6072a209b
title: Using Docker Compose to deploy a lightweight Python REST API with a job queue
author_link: https://medium.com/@mike.p.moritz
author: Mike Moritz
- link: https://robwagner.dev/tortoise-fastapi-setup/
title: Setting up Tortoise ORM with FastAPI
author_link: https://robwagner.dev/
author: Rob Wagner
- link: https://dev.to/dbanty/why-i-m-leaving-flask-3ki6
title: Why I'm Leaving Flask
author_link: https://dev.to/dbanty
author: Dylan Anthony
- link: https://medium.com/python-data/how-to-deploy-tensorflow-2-0-models-as-an-api-service-with-fastapi-docker-128b177e81f3
title: How To Deploy Tensorflow 2.0 Models As An API Service With FastAPI & Docker
author_link: https://medium.com/@bbrenyah
author: Bernard Brenyah
- link: https://testdriven.io/blog/fastapi-crud/
title: "TestDriven.io: Developing and Testing an Asynchronous API with FastAPI and Pytest"
author_link: https://testdriven.io/authors/herman
author: Michael Herman
- link: https://towardsdatascience.com/deploying-iris-classifications-with-fastapi-and-docker-7c9b83fdec3a
title: "Towards Data Science: Deploying Iris Classifications with FastAPI and Docker"
author_link: https://towardsdatascience.com/@mandygu
author: Mandy Gu
- link: https://medium.com/analytics-vidhya/deploy-machine-learning-models-with-keras-fastapi-redis-and-docker-4940df614ece
title: Deploy Machine Learning Models with Keras, FastAPI, Redis and Docker
author_link: https://medium.com/@shane.soh
author: Shane Soh
- link: https://medium.com/@arthur393/another-boilerplate-to-fastapi-azure-pipeline-ci-pytest-3c8d9a4be0bb
title: "Another Boilerplate to FastAPI: Azure Pipeline CI + Pytest"
author_link: https://twitter.com/arthurheinrique
author: Arthur Henrique
- link: https://iwpnd.pw/articles/2020-01/deploy-fastapi-to-aws-lambda
title: How to continuously deploy a FastAPI to AWS Lambda with AWS SAM
author_link: https://iwpnd.pw
author: Benjamin Ramser
- link: https://www.tutlinks.com/create-and-deploy-fastapi-app-to-heroku/
title: Create and Deploy FastAPI app to Heroku without using Docker
author_link: https://www.linkedin.com/in/navule/
author: Navule Pavan Kumar Rao
- link: https://iwpnd.pw/articles/2020-03/apache-kafka-fastapi-geostream
title: Apache Kafka producer and consumer with FastAPI and aiokafka
author_link: https://iwpnd.pw
author: Benjamin Ramser
- link: https://wuilly.com/2019/10/real-time-notifications-with-python-and-postgres/
title: Real-time Notifications with Python and Postgres
author_link: https://wuilly.com/
author: Guillermo Cruz
- link: https://dev.to/paurakhsharma/microservice-in-python-using-fastapi-24cc
title: Microservice in Python using FastAPI
author_link: https://twitter.com/PaurakhSharma
author: Paurakh Sharma Humagain
- link: https://dev.to/cuongld2/build-simple-api-service-with-python-fastapi-part-1-581o
title: Build simple API service with Python FastAPI — Part 1
author_link: https://dev.to/cuongld2
author: cuongld2
- link: https://paulsec.github.io/posts/fastapi_plus_zeit_serverless_fu/
title: FastAPI + Zeit.co = 🚀
author_link: https://twitter.com/PaulWebSec
author: Paul Sec
- link: https://dev.to/tiangolo/build-a-web-api-from-scratch-with-fastapi-the-workshop-2ehe
title: Build a web API from scratch with FastAPI - the workshop
author_link: https://twitter.com/tiangolo
author: Sebastián Ramírez (tiangolo)
- link: https://www.twilio.com/blog/build-secure-twilio-webhook-python-fastapi
title: Build a Secure Twilio Webhook with Python and FastAPI
author_link: https://www.twilio.com
author: Twilio
- link: https://www.stavros.io/posts/fastapi-with-django/
title: Using FastAPI with Django
author_link: https://twitter.com/Stavros
author: Stavros Korokithakis
- link: https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072
title: Introducing Dispatch
author_link: https://netflixtechblog.com/
author: Netflix
- link: https://davidefiocco.github.io/2020/06/27/streamlit-fastapi-ml-serving.html
title: Machine learning model serving in Python using FastAPI and streamlit
author_link: https://github.com/davidefiocco
author: Davide Fiocco
- link: https://www.tutlinks.com/deploy-fastapi-on-azure/
title: Deploy FastAPI on Azure App Service
author_link: https://www.linkedin.com/in/navule/
author: Navule Pavan Kumar Rao
- link: https://towardsdatascience.com/build-and-host-fast-data-science-applications-using-fastapi-823be8a1d6a0
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
japanese:
- link: https://qiita.com/mtitg/items/47770e9a562dd150631d
title: FastAPIDB接続してCRUDするPython製APIサーバーを構築
author_link: https://qiita.com/mtitg
author: "@mtitg"
- link: https://qiita.com/ryoryomaru/items/59958ed385b3571d50de
title: python製の最新APIフレームワーク FastAPI を触ってみた
author_link: https://qiita.com/ryoryomaru
author: "@ryoryomaru"
- link: https://qiita.com/angel_katayoku/items/0e1f5dbbe62efc612a78
title: FastAPIでCORSを回避
author_link: https://qiita.com/angel_katayoku
author: "@angel_katayoku"
- link: https://qiita.com/angel_katayoku/items/4fbc1a4e2b33fa2237d2
title: FastAPIをMySQLと接続してDockerで管理してみる
author_link: https://qiita.com/angel_katayoku
author: "@angel_katayoku"
- link: https://qiita.com/angel_katayoku/items/8a458a8952f50b73f420
title: FastAPIでPOSTされたJSONのレスポンスbodyを受け取る
author_link: https://qiita.com/angel_katayoku
author: "@angel_katayoku"
- link: https://qiita.com/hikarut/items/b178af2e2440c67c6ac4
title: フロントエンド開発者向けのDockerによるPython開発環境構築
author_link: https://qiita.com/hikarut
author: Hikaru Takahashi
- link: https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-environment
title: "【第1回】FastAPIチュートリアル: ToDoアプリを作ってみよう【環境構築編】"
author_link: https://rightcode.co.jp/author/jun
author: ライトコードメディア編集部
- link: https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-model-building
title: "【第2回】FastAPIチュートリアル: ToDoアプリを作ってみよう【モデル構築編】"
author_link: https://rightcode.co.jp/author/jun
author: ライトコードメディア編集部
- link: https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-authentication-user-registration
title: "【第3回】FastAPIチュートリアル: toDoアプリを作ってみよう【認証・ユーザ登録編】"
author_link: https://rightcode.co.jp/author/jun
author: ライトコードメディア編集部
- link: https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-admin-page-improvement
title: "【第4回】FastAPIチュートリアル: toDoアプリを作ってみよう【管理者ページ改良編】"
author_link: https://rightcode.co.jp/author/jun
author: ライトコードメディア編集部
- link: https://qiita.com/bee2/items/0ad260ab9835a2087dae
title: PythonのWeb frameworkのパフォーマンス比較 (Django, Flask, responder, FastAPI, japronto)
author_link: https://qiita.com/bee2
author: "@bee2"
- link: https://qiita.com/bee2/items/75d9c0d7ba20e7a4a0e9
title: "[FastAPI] Python製のASGI Web フレームワーク FastAPIに入門する"
author_link: https://qiita.com/bee2
author: "@bee2"
vietnamese:
- link: https://fullstackstation.com/fastapi-trien-khai-bang-docker/
title: "FASTAPI: TRIỂN KHAI BẰNG DOCKER"
author_link: https://fullstackstation.com/author/figonking/
author: Nguyễn Nhân
russian:
- link: https://habr.com/ru/post/454440/
title: "Мелкая питонячая радость #2: Starlette - Солидная примочка FastAPI"
author_link: https://habr.com/ru/users/57uff3r/
author: Andrey Korchak
- link: https://habr.com/ru/post/478620/
title: Почему Вы должны попробовать FastAPI?
author_link: https://github.com/prostomarkeloff
author: prostomarkeloff
german:
- link: https://blog.codecentric.de/2019/08/inbetriebnahme-eines-scikit-learn-modells-mit-onnx-und-fastapi/
title: Inbetriebnahme eines scikit-learn-Modells mit ONNX und FastAPI
author_link: https://twitter.com/_nicoax
author: Nico Axtmann
podcasts:
english:
- link: https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855
title: FastAPI on PythonBytes
author_link: https://pythonbytes.fm/
author: Python Bytes FM
- link: https://www.pythonpodcast.com/fastapi-web-application-framework-episode-259/
title: "Build The Next Generation Of Python Web Applications With FastAPI - Episode 259 - interview to Sebastían Ramírez (tiangolo)"
author_link: https://www.pythonpodcast.com/
author: Podcast.`__init__`
talks:
english:
- link: https://www.youtube.com/watch?v=3DLwPcrE5mA
title: "PyCon UK 2019: FastAPI from the ground up"
author_link: https://twitter.com/chriswithers13
author: Chris Withers
- link: https://www.youtube.com/watch?v=z9K5pwb0rt8
title: "PyConBY 2020: Serve ML models easily with FastAPI"
author_link: https://twitter.com/tiangolo
author: "Sebastián Ramírez (tiangolo)"
- link: https://www.youtube.com/watch?v=PnpTY1f4k2U
title: "[VIRTUAL] Py.Amsterdam's flying Software Circus: Intro to FastAPI"
author_link: https://twitter.com/tiangolo
author: "Sebastián Ramírez (tiangolo)"

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

View File

@@ -0,0 +1,8 @@
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/
title: Learn to build high-quality web apps with best practices
img: https://fastapi.tiangolo.com/img/sponsors/testdriven.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="17 18 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="11 12 13 14 15 24"
```Python hl_lines="13-17 26"
{!../../../docs_src/additional_responses/tutorial004.py!}
```

View File

@@ -14,7 +14,7 @@ But you also want it to accept new items. And when the items didn't exist before
To achieve that, import `JSONResponse`, and return your content there directly, setting the `status_code` that you want:
```Python hl_lines="2 19"
```Python hl_lines="4 23"
{!../../../docs_src/additional_status_codes/tutorial001.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

@@ -0,0 +1,100 @@
# Async Tests
You have already seen how to test your **FastAPI** applications using the provided `TestClient`, but with it, you can't test or run any other `async` function in your (synchronous) pytest functions.
Being able to use asynchronous functions in your tests could be useful, for example, when you're querying your database asynchronously. Imagine you want to test sending requests to your FastAPI application and then verify that your backend successfully wrote the correct data in the database, while using an async database library.
Let's look at how we can make that work.
## pytest-asyncio
If we want to call asynchronous functions in our tests, our test functions have to be asynchronous. Pytest provides a neat library for this, called `pytest-asyncio`, that allows us to specify that some test functions are to be called asynchronously.
You can install it via:
<div class="termy">
```console
$ pip install pytest-asyncio
---> 100%
```
</div>
## HTTPX
Even if your **FastAPI** application uses normal `def` functions instead of `async def`, it is still an `async` application underneath.
The `TestClient` does some magic inside to call the asynchronous FastAPI application in your normal `def` test functions, using standard pytest. But that magic doesn't work anymore when we're using it inside asynchronous functions. By running our tests asynchronously, we can no longer use the `TestClient` inside our test functions.
Luckily there's a nice alternative, called <a href="https://www.python-httpx.org/" class="external-link" target="_blank">HTTPX</a>.
HTTPX is an HTTP client for Python 3 that allows us to query our FastAPI application similarly to how we did it with the `TestClient`.
If you're familiar with the <a href="https://requests.readthedocs.io/en/master/" class="external-link" target="_blank">Requests</a> library, you'll find that the API of HTTPX is almost identical.
The important difference for us is that with HTTPX we are not limited to synchronous, but can also make asynchronous requests.
## Example
For a simple example, let's consider the following `main.py` module:
```Python
{!../../../docs_src/async_tests/main.py!}
```
The `test_main.py` module that contains the tests for `main.py` could look like this now:
```Python
{!../../../docs_src/async_tests/test_main.py!}
```
## Run it
You can run your tests as usual via:
<div class="termy">
```console
$ pytest
---> 100%
```
</div>
## In Detail
The marker `@pytest.mark.asyncio` tells pytest that this test function should be called asynchronously:
```Python hl_lines="7"
{!../../../docs_src/async_tests/test_main.py!}
```
!!! tip
Note that the test function is now `async def` instead of just `def` as before when using the `TestClient`.
Then we can create an `AsyncClient` with the app, and send async requests to it, using `await`.
```Python hl_lines="9-10"
{!../../../docs_src/async_tests/test_main.py!}
```
This is the equivalent to:
```Python
response = client.get('/')
```
that we used to make our requests with the `TestClient`.
!!! tip
Note that we're using async/await with the new `AsyncClient` - the request is asynchronous.
## Other Asynchronous Function Calls
As the testing function is now asynchronous, you can now also call (and `await`) other `async` functions apart from sending requests to your FastAPI application in your tests, exactly as you would call them anywhere else in your code.
!!! tip
If you encounter a `RuntimeError: Task attached to a different loop` when integrating asynchronous function calls in your tests (e.g. when using <a href="https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop" class="external-link" target="_blank">MongoDB's MotorClient</a>) check out <a href="https://github.com/pytest-dev/pytest-asyncio/issues/38#issuecomment-264418154" class="external-link" target="_blank">this issue</a> in the pytest-asyncio repository.

View File

@@ -0,0 +1,346 @@
# Behind a Proxy
In some situations, you might need to use a **proxy** server like Traefik or Nginx with a configuration that adds an extra path prefix that is not seen by your application.
In these cases you can use `root_path` to configure your application.
The `root_path` is a mechanism provided by the ASGI specification (that FastAPI is built on, through Starlette).
The `root_path` is used to handle these specific cases.
And it's also used internally when mounting sub-applications.
## Proxy with a stripped path prefix
Having a proxy with a stripped path prefix, in this case, means that you could declare a path at `/app` in your code, but then, you add a layer on top (the proxy) that would put your **FastAPI** application under a path like `/api/v1`.
In this case, the original path `/app` would actually be served at `/api/v1/app`.
Even though all your code is written assuming there's just `/app`.
And the proxy would be **"stripping"** the **path prefix** on the fly before transmitting the request to Uvicorn, keep your application convinced that it is serving at `/app`, so that you don't have to update all your code to include the prefix `/api/v1`.
Up to here, everything would work as normally.
But then, when you open the integrated docs UI (the frontend), it would expect to get the OpenAPI schema at `/openapi.json`, instead of `/api/v1/openapi.json`.
So, the frontend (that runs in the browser) would try to reach `/openapi.json` and wouldn't be able to get the OpenAPI schema.
Because we have a proxy with a path prefix of `/api/v1` for our app, the frontend needs to fetch the OpenAPI schema at `/api/v1/openapi.json`.
```mermaid
graph LR
browser("Browser")
proxy["Proxy on http://0.0.0.0:9999/api/v1/app"]
server["Server on http://127.0.0.1:8000/app"]
browser --> proxy
proxy --> server
```
!!! tip
The IP `0.0.0.0` is commonly used to mean that the program listens on all the IPs available in that machine/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-8"
{
"openapi": "3.0.2",
// More stuff here
"servers": [
{
"url": "/api/v1"
}
],
"paths": {
// More stuff here
}
}
```
In this example, the "Proxy" could be something like **Traefik**. And the server would be something like **Uvicorn**, running your FastAPI application.
### Providing the `root_path`
To achieve this, you can use the command line option `--root-path` like:
<div class="termy">
```console
$ uvicorn main:app --root-path /api/v1
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
If you use Hypercorn, it also has the option `--root-path`.
!!! note "Technical Details"
The ASGI specification defines a `root_path` for this use case.
And the `--root-path` command line option provides that `root_path`.
### Checking the current `root_path`
You can get the current `root_path` used by your application for each request, it is part of the `scope` dictionary (that's part of the ASGI spec).
Here we are including it in the message just for demonstration purposes.
```Python hl_lines="8"
{!../../../docs_src/behind_a_proxy/tutorial001.py!}
```
Then, if you start Uvicorn with:
<div class="termy">
```console
$ uvicorn main:app --root-path /api/v1
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
The response would be something like:
```JSON
{
"message": "Hello World",
"root_path": "/api/v1"
}
```
### Setting the `root_path` in the FastAPI app
Alternatively, if you don't have a way to provide a command line option like `--root-path` or equivalent, you can set the `root_path` parameter when creating your FastAPI app:
```Python hl_lines="3"
{!../../../docs_src/behind_a_proxy/tutorial002.py!}
```
Passing the `root_path` to `FastAPI` would be the equivalent of passing the `--root-path` command line option to Uvicorn or Hypercorn.
### About `root_path`
Have in mind that the server (Uvicorn) won't use that `root_path` for anything else than passing it to the app.
But if you go with your browser to <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000/app</a> you will see the normal response:
```JSON
{
"message": "Hello World",
"root_path": "/api/v1"
}
```
So, it won't expect to be accessed at `http://127.0.0.1:8000/api/v1/app`.
Uvicorn will expect the proxy to access Uvicorn at `http://127.0.0.1:8000/app`, and then it would be the proxy's responsibility to add the extra `/api/v1` prefix on top.
## About proxies with a stripped path prefix
Have in mind that a proxy with stripped path prefix is only one of the ways to configure it.
Probably in many cases the default will be that the proxy doesn't have a stripped path prefix.
In a case like that (without a stripped path prefix), the proxy would listen on something like `https://myawesomeapp.com`, and then if the browser goes to `https://myawesomeapp.com/api/v1/app` and your server (e.g. Uvicorn) listens on `http://127.0.0.1:8000` the proxy (without a stripped path prefix) would access Uvicorn at the same path: `http://127.0.0.1:8000/api/v1/app`.
## Testing locally with Traefik
You can easily run the experiment locally with a stripped path prefix using <a href="https://docs.traefik.io/" class="external-link" target="_blank">Traefik</a>.
<a href="https://github.com/containous/traefik/releases" class="external-link" target="_blank">Download Traefik</a>, it's a single binary, you can extract the compressed file and run it directly from the terminal.
Then create a file `traefik.toml` with:
```TOML hl_lines="3"
[entryPoints]
[entryPoints.http]
address = ":9999"
[providers]
[providers.file]
filename = "routes.toml"
```
This tells Traefik to listen on port 9999 and to use another file `routes.toml`.
!!! tip
We are using port 9999 instead of the standard HTTP port 80 so that you don't have to run it with admin (`sudo`) privileges.
Now create that other file `routes.toml`:
```TOML hl_lines="5 12 20"
[http]
[http.middlewares]
[http.middlewares.api-stripprefix.stripPrefix]
prefixes = ["/api/v1"]
[http.routers]
[http.routers.app-http]
entryPoints = ["http"]
service = "app"
rule = "PathPrefix(`/api/v1`)"
middlewares = ["api-stripprefix"]
[http.services]
[http.services.app]
[http.services.app.loadBalancer]
[[http.services.app.loadBalancer.servers]]
url = "http://127.0.0.1:8000"
```
This file configures Traefik to use the path prefix `/api/v1`.
And then it will redirect its requests to your Uvicorn running on `http://127.0.0.1:8000`.
Now start Traefik:
<div class="termy">
```console
$ ./traefik --configFile=traefik.toml
INFO[0000] Configuration loaded from file: /home/user/awesomeapi/traefik.toml
```
</div>
And now start your app with Uvicorn, using the `--root-path` option:
<div class="termy">
```console
$ uvicorn main:app --root-path /api/v1
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
### Check the responses
Now, if you go to the URL with the port for Uvicorn: <a href="http://127.0.0.1:8000/app" class="external-link" target="_blank">http://127.0.0.1:8000/app</a>, you will see the normal response:
```JSON
{
"message": "Hello World",
"root_path": "/api/v1"
}
```
!!! tip
Notice that even though you are accessing it at `http://127.0.0.1:8000/app` it shows the `root_path` of `/api/v1`, taken from the option `--root-path`.
And now open the URL with the port for Traefik, including the path prefix: <a href="http://127.0.0.1:9999/api/v1/app" class="external-link" target="_blank">http://127.0.0.1:9999/api/v1/app</a>.
We get the same response:
```JSON
{
"message": "Hello World",
"root_path": "/api/v1"
}
```
but this time at the URL with the prefix path provided by the proxy: `/api/v1`.
Of course, the idea here is that everyone would access the app through the proxy, so the version with the path prefix `/app/v1` is the "correct" one.
And the version without the path prefix (`http://127.0.0.1:8000/app`), provided by Uvicorn directly, would be exclusively for the _proxy_ (Traefik) to access it.
That demonstrates how the Proxy (Traefik) uses the path prefix and how the server (Uvicorn) uses the `root_path` from the option `--root-path`.
### Check the docs UI
But here's the fun part. ✨
The "official" way to access the app would be through the proxy with the path prefix that we defined. So, as we would expect, if you try the docs UI served by Uvicorn directly, without the path prefix in the URL, it won't work, because it expects to be accessed through the proxy.
You can check it at <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>:
<img src="/img/tutorial/behind-a-proxy/image01.png">
But if we access the docs UI at the "official" URL using the proxy with port `9999`, at `/api/v1/docs`, it works correctly! 🎉
You can check it at <a href="http://127.0.0.1:9999/api/v1/docs" class="external-link" target="_blank">http://127.0.0.1:9999/api/v1/docs</a>:
<img src="/img/tutorial/behind-a-proxy/image02.png">
Right as we wanted it. ✔️
This is because FastAPI uses this `root_path` to create the default `server` in OpenAPI with the URL provided by `root_path`.
## Additional servers
!!! warning
This is a more advanced use case. Feel free to skip it.
By default, **FastAPI** will create a `server` in the OpenAPI schema with the URL for the `root_path`.
But you can also provide other alternative `servers`, for example if you want *the same* docs UI to interact with a staging and production environments.
If you pass a custom list of `servers` and there's a `root_path` (because your API lives behind a proxy), **FastAPI** will insert a "server" with this `root_path` at the beginning of the list.
For example:
```Python hl_lines="4-7"
{!../../../docs_src/behind_a_proxy/tutorial003.py!}
```
Will generate an OpenAPI schema like:
```JSON hl_lines="5-7"
{
"openapi": "3.0.2",
// More stuff here
"servers": [
{
"url": "/api/v1"
},
{
"url": "https://stag.example.com",
"description": "Staging environment"
},
{
"url": "https://prod.example.com",
"description": "Production environment"
}
],
"paths": {
// More stuff here
}
}
```
!!! tip
Notice the auto-generated server with a `url` value of `/api/v1`, taken from the `root_path`.
In the docs UI at <a href="http://127.0.0.1:9999/api/v1/docs" class="external-link" target="_blank">http://127.0.0.1:9999/api/v1/docs</a> it would look like:
<img src="/img/tutorial/behind-a-proxy/image03.png">
!!! tip
The docs UI will interact with the server that you select.
### Disable automatic server from `root_path`
If you don't want **FastAPI** to include an automatic server using the `root_path`, you can use the parameter `root_path_in_servers=False`:
```Python hl_lines="9"
{!../../../docs_src/behind_a_proxy/tutorial004.py!}
```
and then it won't include it in the OpenAPI schema.
## Mounting a sub-application
If you need to mount a sub-application (as described in [Sub Applications - Mounts](./sub-applications.md){.internal-link target=_blank}) while also using a proxy with `root_path`, you can do it normally, as you would expect.
FastAPI will internally use the `root_path` smartly, so it will just work. ✨

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!}
```
@@ -203,6 +203,21 @@ File responses will include appropriate `Content-Length`, `Last-Modified` and `E
{!../../../docs_src/custom_response/tutorial009.py!}
```
## Default response class
When creating a **FastAPI** class instance or an `APIRouter` you can specify which response class to use by default.
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"
{!../../../docs_src/custom_response/tutorial010.py!}
```
!!! tip
You can still override `response_class` in *path operations* as before.
## Additional documentation
You can also declare the media type and many other details in OpenAPI using `responses`: [Additional Responses in OpenAPI](additional-responses.md){.internal-link target=_blank}.

View File

@@ -4,6 +4,9 @@ You can define event handlers (functions) that need to be executed before the ap
These functions can be declared with `async def` or normal `def`.
!!! warning
Only event handlers for the main application will be executed, not for [Sub Applications - Mounts](./sub-applications.md){.internal-link target=_blank}.
## `startup` event
To add a function that should be run before the application starts, declare it with the event `"startup"`:
@@ -41,4 +44,4 @@ Here, the `shutdown` event handler function will write a text line `"Application
So, we declare the event handler function with standard `def` instead of `async def`.
!!! info
You can read more about these event handlers in <a href="https://www.starlette.io/events/" class="external-link" target="_blank">Starlette's Events' docs</a>.
You can read more about these event handlers in <a href="https://www.starlette.io/events/" class="external-link" target="_blank">Starlette's Events' docs</a>.

View File

@@ -32,7 +32,6 @@ And that function `get_openapi()` receives as parameters:
* `openapi_version`: The version of the OpenAPI specification used. By default, the latest: `3.0.2`.
* `description`: The description of your API.
* `routes`: A list of routes, these are each of the registered *path operations*. They are taken from `app.routes`.
* `openapi_prefix`: The URL prefix to be used in your OpenAPI.
## Overriding the defaults
@@ -44,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!}
```
@@ -52,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!}
```
@@ -60,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!}
```
@@ -72,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!}
```
@@ -173,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!}
```
@@ -225,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!}
```
@@ -240,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="6 7 8"
```Python hl_lines="3-5"
{!../../../docs_src/nosql_databases/tutorial001.py!}
```
@@ -29,7 +29,7 @@ We will use it later as a fixed field `type` in our documents.
This is not required by Couchbase, but is a good practice that will help you afterwards.
```Python hl_lines="10"
```Python hl_lines="9"
{!../../../docs_src/nosql_databases/tutorial001.py!}
```
@@ -54,7 +54,7 @@ This utility function will:
* Set defaults for timeouts.
* Return it.
```Python hl_lines="13 14 15 16 17 18 19 20 21 22"
```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="25 26 27 28 29"
```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="32 33 34"
```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="37 38 39 40 41 42 43"
```Python hl_lines="36-42"
{!../../../docs_src/nosql_databases/tutorial001.py!}
```
@@ -135,7 +135,7 @@ UserInDB(username="johndoe", hashed_password="some_hash")
### Create the `FastAPI` app
```Python hl_lines="47"
```Python hl_lines="46"
{!../../../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="50 51 52 53 54"
```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="8 9 10 11 12 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53"
```Python hl_lines="10-14 37-54"
{!../../../docs_src/openapi_callbacks/tutorial001.py!}
```
@@ -92,7 +92,7 @@ Because of that, you need to declare what will be the `default_response_class`,
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="3 24"
```Python hl_lines="5 26"
{!../../../docs_src/openapi_callbacks/tutorial001.py!}
```
@@ -105,7 +105,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="15 16 17 20 21 27 28 29 30 31"
```Python hl_lines="17-19 22-23 29-33"
{!../../../docs_src/openapi_callbacks/tutorial001.py!}
```
@@ -172,7 +172,7 @@ At this point you have the *callback path operation(s)* needed (the one(s) that
Now use the parameter `callbacks` in *your API's path operation decorator* to pass the attribute `.routes` (that's actually just a `list` of routes/*path operations*) from that callback router:
```Python hl_lines="34"
```Python hl_lines="36"
{!../../../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="4 6 20 21"
```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 5 9 13 47 65 106 108 109 110 111 112 113 114 115 116 122 123 124 125 129 130 131 132 133 134 135 140 154"
```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="63 64 65 66"
```Python hl_lines="62-65"
{!../../../docs_src/security/tutorial005.py!}
```
@@ -93,7 +93,7 @@ And we return the scopes as part of the JWT token.
But in your application, for security, you should make sure you only add the scopes that the user is actually able to have, or the ones you have predefined.
```Python hl_lines="155"
```Python hl_lines="153"
{!../../../docs_src/security/tutorial005.py!}
```
@@ -118,7 +118,7 @@ In this case, it requires the scope `me` (it could require more than one scope).
We are doing it here to demonstrate how **FastAPI** handles scopes declared at different levels.
```Python hl_lines="5 140 167"
```Python hl_lines="4 139 166"
{!../../../docs_src/security/tutorial005.py!}
```
@@ -143,7 +143,7 @@ We also declare a special parameter of type `SecurityScopes`, imported from `fas
This `SecurityScopes` class is similar to `Request` (`Request` was used to get the request object directly).
```Python hl_lines="9 106"
```Python hl_lines="8 105"
{!../../../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="106 108 109 110 111 112 113 114 115 116"
```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="47 117 118 119 120 121 122 123 124 125 126 127 128"
```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="129 130 131 132 133 134 135"
```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

@@ -1,100 +0,0 @@
# Sub Applications - Behind a Proxy, Mounts
There are at least two situations where you could need to create your **FastAPI** application using some specific paths.
But then you need to set them up to be served with a path prefix.
It could happen if you have a:
* **Proxy** server.
* You are "**mounting**" a FastAPI application inside another FastAPI application (or inside another ASGI application, like Starlette).
## Proxy
Having a proxy in this case means that you could declare a path at `/app`, but then, you could need to add a layer on top (the Proxy) that would put your **FastAPI** application under a path like `/api/v1`.
In this case, the original path `/app` will actually be served at `/api/v1/app`.
Even though your application "thinks" it is serving at `/app`.
And the Proxy could be re-writing the path "on the fly" to keep your application convinced that it is serving at `/app`.
Up to here, everything would work as normally.
But then, when you open the integrated docs, they would expect to get the OpenAPI schema at `/openapi.json`, instead of `/api/v1/openapi.json`.
So, the frontend (that runs in the browser) would try to reach `/openapi.json` and wouldn't be able to get the OpenAPI schema.
So, it's needed that the frontend looks for the OpenAPI schema at `/api/v1/openapi.json`.
And it's also needed that the returned JSON OpenAPI schema has the defined path at `/api/v1/app` (behind the proxy) instead of `/app`.
---
For these cases, you can declare an `openapi_prefix` parameter in your `FastAPI` application.
See the section below, about "mounting", for an example.
## Mounting a **FastAPI** application
"Mounting" means adding a complete "independent" application in a specific path, that then takes care of handling all the sub-paths.
You could want to do this if you have several "independent" applications that you want to separate, having their own independent OpenAPI schema and user interfaces.
### Top-level application
First, create the main, top-level, **FastAPI** application, and its *path operations*:
```Python hl_lines="3 6 7 8"
{!../../../docs_src/sub_applications/tutorial001.py!}
```
### Sub-application
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".
When creating the sub-application, use the parameter `openapi_prefix`. In this case, with a prefix of `/subapi`:
```Python hl_lines="11 14 15 16"
{!../../../docs_src/sub_applications/tutorial001.py!}
```
### Mount the sub-application
In your top-level application, `app`, mount the sub-application, `subapi`.
Here you need to make sure you use the same path that you used for the `openapi_prefix`, in this case, `/subapi`:
```Python hl_lines="11 19"
{!../../../docs_src/sub_applications/tutorial001.py!}
```
## Check the automatic API docs
Now, run `uvicorn`, if your file is at `main.py`, it would be:
<div class="termy">
```console
$ uvicorn main:app --reload
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
And open the docs at <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
You will see the automatic API docs for the main app, including only its own paths:
<img src="/img/tutorial/sub-applications/image01.png">
And then, open the docs for the sub-application, at <a href="http://127.0.0.1:8000/subapi/docs" class="external-link" target="_blank">http://127.0.0.1:8000/subapi/docs</a>.
You will see the automatic API docs for the sub-application, including only its own sub-paths, with their correct prefix:
<img src="/img/tutorial/sub-applications/image02.png">
If you try interacting with any of the two user interfaces, they will work, because the browser will be able to talk to the correct path (or sub-path).

View File

@@ -0,0 +1,73 @@
# Sub Applications - Mounts
If you need to have two independent FastAPI applications, with their own independent OpenAPI and their own docs UIs, you can have a main app and "mount" one (or more) sub-application(s).
## Mounting a **FastAPI** application
"Mounting" means adding a completely "independent" application in a specific path, that then takes care of handling everything under that path, with the _path operations_ declared in that sub-application.
### Top-level application
First, create the main, top-level, **FastAPI** application, and its *path operations*:
```Python hl_lines="3 6-8"
{!../../../docs_src/sub_applications/tutorial001.py!}
```
### Sub-application
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-16"
{!../../../docs_src/sub_applications/tutorial001.py!}
```
### Mount the sub-application
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"
{!../../../docs_src/sub_applications/tutorial001.py!}
```
### Check the automatic API docs
Now, run `uvicorn` with the main app, if your file is `main.py`, it would be:
<div class="termy">
```console
$ uvicorn main:app --reload
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
And open the docs at <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
You will see the automatic API docs for the main app, including only its own _path operations_:
<img src="/img/tutorial/sub-applications/image01.png">
And then, open the docs for the sub-application, at <a href="http://127.0.0.1:8000/subapi/docs" class="external-link" target="_blank">http://127.0.0.1:8000/subapi/docs</a>.
You will see the automatic API docs for the sub-application, including only its own _path operations_, all under the correct sub-path prefix `/subapi`:
<img src="/img/tutorial/sub-applications/image02.png">
If you try interacting with any of the two user interfaces, they will work correctly, because the browser will be able to talk to each specific app or sub-app.
### Technical Details: `root_path`
When you mount a sub-application as described above, FastAPI will take care of communicating the mount path for the sub-application using a mechanism from the ASGI specification called a `root_path`.
That way, the sub-application will know to use that path prefix for the docs UI.
And the sub-application could also have its own mounted sub-applications and everything would work correctly, because FastAPI handles all these `root_path`s automatically.
You will learn more about the `root_path` and how to use it explicitly in the section about [Behind a Proxy](./behind-a-proxy.md){.internal-link target=_blank}.

View File

@@ -39,13 +39,16 @@ $ 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="3 10 14 15"
```Python hl_lines="4 11 15-16"
{!../../../docs_src/templates/tutorial001.py!}
```
!!! note
Notice that you have to pass the `request` as part of the key-value pairs in the context for Jinja2. So, you also have to declare it in your *path operation*.
!!! tip
By declaring `response_class=HTMLResponse` the docs UI will be able to know that the response will be HTML.
!!! note "Technical Details"
You could also use `from starlette.templating import Jinja2Templates`.

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="24 25 28"
```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,6 +4,9 @@ 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!}
```
!!! note
For more details, check Starlette's documentation for <a href="https://www.starlette.io/testclient/#testing-websocket-sessions" class="external-link" target="_blank">testing WebSockets</a>.

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,44 +45,13 @@ 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!}
```
You can receive and send binary, text, and JSON data.
## Using `Depends` and others
In WebSocket endpoints you can import from `fastapi` and use:
* `Depends`
* `Security`
* `Cookie`
* `Header`
* `Path`
* `Query`
They work the same way as for other FastAPI endpoints/*path operations*:
```Python hl_lines="53 54 55 56 57 58 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76"
{!../../../docs_src/websockets/tutorial002.py!}
```
!!! info
In a WebSocket it doesn't really make sense to raise an `HTTPException`. So it's better to close the WebSocket connection directly.
You can use a closing code from the <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1" class="external-link" target="_blank">valid codes defined in the specification</a>.
In the future, there will be a `WebSocketException` that you will be able to `raise` from anywhere, and add exception handlers for it. It depends on the <a href="https://github.com/encode/starlette/pull/527" class="external-link" target="_blank">PR #527</a> in Starlette.
## More info
To learn more about the options, check Starlette's documentation for:
* <a href="https://www.starlette.io/websockets/" class="external-link" target="_blank">The `WebSocket` class</a>.
* <a href="https://www.starlette.io/endpoints/#websocketendpoint" class="external-link" target="_blank">Class-based WebSocket handling</a>.
## Test it
## Try it
If your file is named `main.py`, run your application with:
@@ -115,3 +84,89 @@ You can send (and receive) many messages:
<img src="/img/tutorial/websockets/image04.png">
And all of them will use the same WebSocket connection.
## Using `Depends` and others
In WebSocket endpoints you can import from `fastapi` and use:
* `Depends`
* `Security`
* `Cookie`
* `Header`
* `Path`
* `Query`
They work the same way as for other FastAPI endpoints/*path operations*:
```Python hl_lines="58-65 68-83"
{!../../../docs_src/websockets/tutorial002.py!}
```
!!! info
In a WebSocket it doesn't really make sense to raise an `HTTPException`. So it's better to close the WebSocket connection directly.
You can use a closing code from the <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1" class="external-link" target="_blank">valid codes defined in the specification</a>.
In the future, there will be a `WebSocketException` that you will be able to `raise` from anywhere, and add exception handlers for it. It depends on the <a href="https://github.com/encode/starlette/pull/527" class="external-link" target="_blank">PR #527</a> in Starlette.
### Try the WebSockets with dependencies
If your file is named `main.py`, run your application with:
<div class="termy">
```console
$ uvicorn main:app --reload
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
Open your browser at <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>.
There you can set:
* The "Item ID", used in the path.
* The "Token" used as a query parameter.
!!! tip
Notice that the query `token` will be handled by a dependency.
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:
* <a href="https://www.starlette.io/websockets/" class="external-link" target="_blank">The `WebSocket` class</a>.
* <a href="https://www.starlette.io/endpoints/#websocketendpoint" class="external-link" target="_blank">Class-based WebSocket handling</a>.

View File

@@ -1,6 +1,6 @@
# Including WSGI - Flask, Django, others
You can mount WSGI applications as you saw with [Sub Applications - Behind a Proxy, Mounts](./sub-applications-proxy.md){.internal-link target=_blank}.
You can mount WSGI applications as you saw with [Sub Applications - Mounts](./sub-applications.md){.internal-link target=_blank}, [Behind a Proxy](./behind-a-proxy.md){.internal-link target=_blank}.
For that, you can use the `WSGIMiddleware` and use it to wrap your WSGI application, for example, Flask, Django, etc.
@@ -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,11 +261,11 @@ 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`
Modern versions of python have a very intuitive way to define asynchronous code. This makes it look just like normal "sequential" code and do the "awaiting" for you at the right moments.
Modern versions of Python have a very intuitive way to define asynchronous code. This makes it look just like normal "sequential" code and do the "awaiting" for you at the right moments.
When there is an operation that will require waiting before giving the results and has support for these new Python features, you can code it like:
@@ -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,9 +334,9 @@ 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 lead to <a href="http://callbackhell.com/" class="external-link" target="_blank">callback hell</a>.
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>.
## Coroutines

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

@@ -499,13 +499,3 @@ $ bash scripts/test-cov-html.sh
</div>
This command generates a directory `./htmlcov/`, if you open the file `./htmlcov/index.html` in your browser, you can explore interactively the regions of code that are covered by the tests, and notice if there is any region missing.
### Tests in your editor
If you want to use the integrated tests in your editor add `./docs_src` to your `PYTHONPATH` variable.
For example, in VS Code you can create a file `.env` with:
```env
PYTHONPATH=./docs_src
```

View File

@@ -1,13 +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;
}
.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,394 +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 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: 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 see 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

@@ -7,113 +7,72 @@ There are many posts, articles, tools, and projects, related to **FastAPI**.
Here's an incomplete list of some of them.
!!! tip
If you have an article, project, tool, or anything related to **FastAPI** that is not yet listed here, create a <a href="https://github.com/tiangolo/fastapi/edit/master/docs/external-links.md" class="external-link" target="_blank">Pull Request adding it</a>.
If you have an article, project, tool, or anything related to **FastAPI** that is not yet listed here, create a <a href="https://github.com/tiangolo/fastapi/edit/master/docs/en/data/external_links.yml" class="external-link" target="_blank">Pull Request adding it</a>.
## Articles
### English
* <a href="https://medium.com/@williamhayes/fastapi-starlette-debug-vs-prod-5f7561db3a59" class="external-link" target="_blank">FastAPI/Starlette debug vs prod</a> by <a href="https://medium.com/@williamhayes" class="external-link" target="_blank">William Hayes</a>.
{% if external_links %}
{% for article in external_links.articles.english %}
* <a href="https://medium.com/data-rebels/fastapi-google-as-an-external-authentication-provider-3a527672cf33" class="external-link" target="_blank">FastAPIGoogle as an external authentication provider</a> by <a href="https://medium.com/@nils_29588" class="external-link" target="_blank">Nils de Bruin</a>.
* <a href="https://medium.com/data-rebels/fastapi-how-to-add-basic-and-cookie-authentication-a45c85ef47d3" class="external-link" target="_blank">FastAPIHow to add basic and cookie authentication</a> by <a href="https://medium.com/@nils_29588" class="external-link" target="_blank">Nils de Bruin</a>.
* <a href="https://dev.to/errietta/introduction-to-the-fastapi-python-framework-2n10" class="external-link" target="_blank">Introduction to the fastapi python framework</a> by <a href="https://dev.to/errietta" class="external-link" target="_blank">Errieta Kostala</a>.
* <a href="http://nickc1.github.io/api,/scikit-learn/2019/01/10/scikit-fastapi.html" class="external-link" target="_blank">FastAPI and Scikit-Learn: Easily Deploy Models</a> by <a href="http://nickc1.github.io/" class="external-link" target="_blank">Nick Cortale</a>.
* <a href="https://medium.com/data-rebels/fastapi-authentication-revisited-enabling-api-key-authentication-122dc5975680" class="external-link" target="_blank">FastAPI authentication revisited: Enabling API key authentication</a> by <a href="https://medium.com/@nils_29588" class="external-link" target="_blank">Nils de Bruin</a>.
* <a href="https://blog.bartab.fr/fastapi-logging-on-the-fly/" class="external-link" target="_blank">FastAPI, a simple use case on logging</a> by <a href="https://blog.bartab.fr/" class="external-link" target="_blank">@euri10</a>.
* <a href="https://medium.com/@nico.axtmann95/deploying-a-scikit-learn-model-with-onnx-und-fastapi-1af398268915" class="external-link" target="_blank">Deploying a scikit-learn model with ONNX and FastAPI</a> by <a href="https://www.linkedin.com/in/nico-axtmann" class="external-link" target="_blank">Nico Axtmann</a>.
* <a href="https://geekflare.com/python-asynchronous-web-frameworks/" class="external-link" target="_blank">Top 5 Asynchronous Web Frameworks for Python</a> by <a href="https://geekflare.com/author/ankush/" class="external-link" target="_blank">Ankush Thakur</a> on <a href="https://geekflare.com" class="external-link" target="_blank">GeekFlare</a>.
* <a href="https://medium.com/@gntrm/jwt-authentication-with-fastapi-and-aws-cognito-1333f7f2729e" class="external-link" target="_blank">JWT Authentication with FastAPI and AWS Cognito</a> by <a href="https://twitter.com/gntrm" class="external-link" target="_blank">Johannes Gontrum</a>.
* <a href="https://towardsdatascience.com/how-to-deploy-a-machine-learning-model-dc51200fe8cf" class="external-link" target="_blank">How to Deploy a Machine Learning Model</a> by <a href="https://www.linkedin.com/in/mgrootendorst/" class="external-link" target="_blank">Maarten Grootendorst</a> on <a href="https://towardsdatascience.com/" class="external-link" target="_blank">Towards Data Science</a>.
* [Uber: Ludwig v0.2 Adds New Features and Other Improvements to its Deep Learning Toolbox [including a FastAPI server]](https://eng.uber.com/ludwig-v0-2/){.external-link target=_blank} on <a href="https://eng.uber.com" class="external-link" target="_blank">Uber Engineering</a>.
* <a href="https://gitlab.com/euri10/fastapi_cheatsheet" class="external-link" target="_blank">A FastAPI and Swagger UI visual cheatsheet</a> by <a href="https://gitlab.com/euri10" class="external-link" target="_blank">@euri10</a>
* <a href="https://medium.com/@mike.p.moritz/using-docker-compose-to-deploy-a-lightweight-python-rest-api-with-a-job-queue-37e6072a209b" class="external-link" target="_blank">Using Docker Compose to deploy a lightweight Python REST API with a job queue</a> by <a href="https://medium.com/@mike.p.moritz" class="external-link" target="_blank">Mike Moritz</a>.
* <a href="https://robwagner.dev/tortoise-fastapi-setup/" class="external-link" target="_blank">Setting up Tortoise ORM with FastAPI</a> by <a href="https://robwagner.dev/" class="external-link" target="_blank">Rob Wagner</a>.
* <a href="https://dev.to/dbanty/why-i-m-leaving-flask-3ki6" class="external-link" target="_blank">Why I'm Leaving Flask</a> by <a href="https://dev.to/dbanty" class="external-link" target="_blank">Dylan Anthony</a>.
* <a href="https://medium.com/python-data/how-to-deploy-tensorflow-2-0-models-as-an-api-service-with-fastapi-docker-128b177e81f3" class="external-link" target="_blank">How To Deploy Tensorflow 2.0 Models As An API Service With FastAPI & Docker</a> by <a href="https://medium.com/@bbrenyah" class="external-link" target="_blank">Bernard Brenyah</a>.
* <a href="https://testdriven.io/blog/fastapi-crud/" class="external-link" target="_blank">TestDriven.io: Developing and Testing an Asynchronous API with FastAPI and Pytest</a> by <a href="https://testdriven.io/authors/herman/" class="external-link" target="_blank">Michael Herman</a>.
* <a href="https://towardsdatascience.com/deploying-iris-classifications-with-fastapi-and-docker-7c9b83fdec3a" class="external-link" target="_blank">Towards Data Science: Deploying Iris Classifications with FastAPI and Docker</a> by <a href="https://towardsdatascience.com/@mandygu" class="external-link" target="_blank">Mandy Gu</a>.
* <a href="https://medium.com/analytics-vidhya/deploy-machine-learning-models-with-keras-fastapi-redis-and-docker-4940df614ece" class="external-link" target="_blank">Deploy Machine Learning Models with Keras, FastAPI, Redis and Docker</a> by <a href="https://medium.com/@shane.soh" class="external-link" target="_blank">Shane Soh</a>.
* <a href="https://medium.com/@arthur393/another-boilerplate-to-fastapi-azure-pipeline-ci-pytest-3c8d9a4be0bb" class="external-link" target="_blank">Another Boilerplate to FastAPI: Azure Pipeline CI + Pytest</a> by <a href="https://twitter.com/arthurheinrique" class="external-link" target="_blank">Arthur Henrique</a>.
* <a href="https://iwpnd.pw/articles/2020-01/deploy-fastapi-to-aws-lambda" class="external-link" target="_blank">How to continuously deploy a FastAPI to AWS Lambda with AWS SAM</a> by <a href="https://iwpnd.pw" class="external-link" target="_blank">Benjamin Ramser</a>.
* <a href="https://www.tutlinks.com/create-and-deploy-fastapi-app-to-heroku/" class="external-link" target="_blank">Create and Deploy FastAPI app to Heroku without using Docker</a> by <a href="https://www.linkedin.com/in/navule/" class="external-link" target="_blank">Navule Pavan Kumar Rao</a>.
* <a href="https://iwpnd.pw/articles/2020-03/apache-kafka-fastapi-geostream" class="external-link" target="_blank">Apache Kafka producer and consumer with FastAPI and aiokafka</a> by <a href="https://iwpnd.pw" class="external-link" target="_blank">Benjamin Ramser</a>.
* <a href="{{ article.link }}" class="external-link" target="_blank">{{ article.title }}</a> by <a href="{{ article.author_link }}" class="external-link" target="_blank">{{ article.author }}</a>.
{% endfor %}
{% endif %}
### Japanese
* <a href="https://qiita.com/mtitg/items/47770e9a562dd150631d" class="external-link" target="_blank">FastAPIDB接続してCRUDするPython製APIサーバーを構築</a> by <a href="https://qiita.com/mtitg" class="external-link" target="_blank">@mtitg</a>.
{% if external_links %}
{% for article in external_links.articles.japanese %}
* <a href="https://qiita.com/ryoryomaru/items/59958ed385b3571d50de" class="external-link" target="_blank">python製の最新APIフレームワーク FastAPI を触ってみた</a> by <a href="https://qiita.com/ryoryomaru" class="external-link" target="_blank">@ryoryomaru</a>.
* <a href="https://qiita.com/angel_katayoku/items/0e1f5dbbe62efc612a78" class="external-link" target="_blank">FastAPIでCORSを回避</a> by <a href="https://qiita.com/angel_katayoku" class="external-link" target="_blank">@angel_katayoku</a>.
* <a href="https://qiita.com/angel_katayoku/items/4fbc1a4e2b33fa2237d2" class="external-link" target="_blank">FastAPIをMySQLと接続してDockerで管理してみる</a> by <a href="https://qiita.com/angel_katayoku" class="external-link" target="_blank">@angel_katayoku</a>.
* <a href="https://qiita.com/angel_katayoku/items/8a458a8952f50b73f420" class="external-link" target="_blank">FastAPIでPOSTされたJSONのレスポンスbodyを受け取る</a> by <a href="https://qiita.com/angel_katayoku" class="external-link" target="_blank">@angel_katayoku</a>.
* <a href="https://qiita.com/hikarut/items/b178af2e2440c67c6ac4" class="external-link" target="_blank">フロントエンド開発者向けのDockerによるPython開発環境構築</a> by <a href="https://qiita.com/hikarut" class="external-link" target="_blank">Hikaru Takahashi</a>.
* <a href="https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-environment" class="external-link" target="_blank">【第1回】FastAPIチュートリアル: ToDoアプリを作ってみよう【環境構築編】</a> by <a href="https://rightcode.co.jp/author/jun" class="external-link" target="_blank">ライトコードメディア編集部</a>
* <a href="https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-model-building" class="external-link" target="_blank">【第2回】FastAPIチュートリアル: ToDoアプリを作ってみよう【モデル構築編】</a> by <a href="https://rightcode.co.jp/author/jun" class="external-link" target="_blank">ライトコードメディア編集部</a>
* <a href="https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-authentication-user-registration" class="external-link" target="_blank">【第3回】FastAPIチュートリアル: toDoアプリを作ってみよう【認証・ユーザ登録編】</a> by <a href="https://rightcode.co.jp/author/jun" class="external-link" target="_blank">ライトコードメディア編集部</a>
* <a href="https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-admin-page-improvement" class="external-link" target="_blank">【第4回】FastAPIチュートリアル: toDoアプリを作ってみよう【管理者ページ改良編】</a> by <a href="https://rightcode.co.jp/author/jun" class="external-link" target="_blank">ライトコードメディア編集部</a>
* <a href="https://qiita.com/bee2/items/0ad260ab9835a2087dae" class="external-link" target="_blank">PythonのWeb frameworkのパフォーマンス比較 (Django, Flask, responder, FastAPI, japronto)</a> by <a href="https://qiita.com/bee2" class="external-link" target="_blank">@bee2</a>.
* <a href="https://qiita.com/bee2/items/75d9c0d7ba20e7a4a0e9" class="external-link" target="_blank">[FastAPI] Python製のASGI Web フレームワーク FastAPIに入門する</a> by <a href="https://qiita.com/bee2" class="external-link" target="_blank">@bee2</a>.
### Chinese
* <a href="https://cloud.tencent.com/developer/article/1431448" class="external-link" target="_blank">使用FastAPI框架快速构建高性能的api服务</a> by <a href="https://cloud.tencent.com/developer/user/5471722" class="external-link" target="_blank">逍遥散人</a>.
* <a href="https://wxq0309.github.io/" class="external-link" target="_blank">FastAPI框架中文文档</a> by <a href="https://wxq0309.github.io/" class="external-link" target="_blank">何大仙</a>.
* <a href="{{ article.link }}" class="external-link" target="_blank">{{ article.title }}</a> by <a href="{{ article.author_link }}" class="external-link" target="_blank">{{ article.author }}</a>.
{% endfor %}
{% endif %}
### Vietnamese
* <a href="https://fullstackstation.com/fastapi-trien-khai-bang-docker/" class="external-link" target="_blank">FASTAPI: TRIỂN KHAI BẰNG DOCKER</a> by <a href="https://fullstackstation.com/author/figonking/" class="external-link" target="_blank">Nguyễn Nhân</a>.
{% if external_links %}
{% for article in external_links.articles.vietnamese %}
* <a href="{{ article.link }}" class="external-link" target="_blank">{{ article.title }}</a> by <a href="{{ article.author_link }}" class="external-link" target="_blank">{{ article.author }}</a>.
{% endfor %}
{% endif %}
### Russian
* <a href="https://habr.com/ru/post/454440/" class="external-link" target="_blank">Мелкая питонячая радость #2: Starlette - Солидная примочка FastAPI</a> by <a href="https://habr.com/ru/users/57uff3r/" class="external-link" target="_blank">Andrey Korchak</a>.
{% if external_links %}
{% for article in external_links.articles.russian %}
* <a href="https://habr.com/ru/post/478620/" class="external-link" target="_blank">Почему Вы должны попробовать FastAPI?</a> by <a href="https://github.com/prostomarkeloff" class="external-link" target="_blank">prostomarkeloff</a>.
* <a href="{{ article.link }}" class="external-link" target="_blank">{{ article.title }}</a> by <a href="{{ article.author_link }}" class="external-link" target="_blank">{{ article.author }}</a>.
{% endfor %}
{% endif %}
### German
* <a href="https://blog.codecentric.de/2019/08/inbetriebnahme-eines-scikit-learn-modells-mit-onnx-und-fastapi/" class="external-link" target="_blank">Inbetriebnahme eines scikit-learn-Modells mit ONNX und FastAPI</a> by <a href="https://twitter.com/_nicoax" class="external-link" target="_blank">Nico Axtmann</a>.
{% if external_links %}
{% for article in external_links.articles.german %}
* <a href="{{ article.link }}" class="external-link" target="_blank">{{ article.title }}</a> by <a href="{{ article.author_link }}" class="external-link" target="_blank">{{ article.author }}</a>.
{% endfor %}
{% endif %}
## Podcasts
* <a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" class="external-link" target="_blank">FastAPI on PythonBytes</a> by <a href="https://pythonbytes.fm/" class="external-link" target="_blank">Python Bytes FM</a>.
{% if external_links %}
{% for article in external_links.podcasts.english %}
* <a href="{{ article.link }}" class="external-link" target="_blank">{{ article.title }}</a> by <a href="{{ article.author_link }}" class="external-link" target="_blank">{{ article.author }}</a>.
{% endfor %}
{% endif %}
## Talks
* <a href="https://www.youtube.com/watch?v=3DLwPcrE5mA" class="external-link" target="_blank">PyCon UK 2019: FastAPI from the ground up</a> by <a href="https://twitter.com/chriswithers13" class="external-link" target="_blank">Chris Withers</a>.
{% if external_links %}
{% for article in external_links.talks.english %}
* <a href="{{ article.link }}" class="external-link" target="_blank">{{ article.title }}</a> by <a href="{{ article.author_link }}" class="external-link" target="_blank">{{ article.author }}</a>.
{% endfor %}
{% endif %}
## Projects

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.
@@ -71,7 +71,7 @@ my_second_user: User = User(**second_user_data)
### Editor support
All the framework was designed to be easy and intuitive to use, all the decisions where tested on multiple editors even before starting development, to ensure the best development experience.
All the framework was designed to be easy and intuitive to use, all the decisions were tested on multiple editors even before starting development, to ensure the best development experience.
In the last Python developer survey it was clear <a href="https://www.jetbrains.com/research/python-developers-survey-2017/#tools-and-features" class="external-link" target="_blank">that the most used feature is "autocompletion"</a>.

View File

@@ -12,28 +12,18 @@ And there are several ways to get help too.
## Star **FastAPI** in GitHub
You can "star" FastAPI in GitHub (clicking the star button at the top right): <a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>.
You can "star" FastAPI in GitHub (clicking the star button at the top right): <a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>. ⭐️
By adding a star, other users will be able to find it more easily and see that it has been already useful for others.
## Watch the GitHub repository for releases
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>.
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>. 👀
There you can select "Releases only".
Doing it, you will receive notifications (in your email) whenever there's a new release (a new version) of **FastAPI** with bug fixes and new features.
## 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 chat on Gitter: <a href="https://gitter.im/tiangolo/fastapi" class="external-link" target="_blank">https://gitter.im/tiangolo/fastapi</a>.
There you can ask quick questions, help others, share ideas, etc.
## Connect with the author
You can connect with <a href="https://tiangolo.com" class="external-link" target="_blank">me (Sebastián Ramírez / `tiangolo`)</a>, the author.
@@ -45,39 +35,32 @@ You can:
* Follow me to see when I create a new Open Source project.
* <a href="https://twitter.com/tiangolo" class="external-link" target="_blank">Follow me on **Twitter**</a>.
* Tell me how you use FastAPI (I love to hear that).
* Ask questions.
* Hear when I make announcements or release new tools.
* <a href="https://www.linkedin.com/in/tiangolo/" class="external-link" target="_blank">Connect with me on **Linkedin**</a>.
* Talk to me.
* Endorse me or recommend me :)
* <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">Read what I write (or follow me) on **Medium**</a>.
* Read other ideas, articles and tools I have created.
* Follow me to see when I publish something new.
* Hear when I make announcements or release new tools (although I use Twitter more often 🤷‍♂).
* Read what I write (or follow me) on <a href="https://dev.to/tiangolo" class="external-link" target="_blank">**Dev.to**</a> or <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">**Medium**</a>.
* Read other ideas, articles, and about tools I have created.
* Follow me to read when I publish something new.
## Tweet about **FastAPI**
<a href="https://twitter.com/compose/tweet?text=I'm loving FastAPI because... https://github.com/tiangolo/fastapi cc @tiangolo" class="external-link" target="_blank">Tweet about **FastAPI**</a> and let me and others know why you like it.
## Let me know how are you using **FastAPI**
<a href="https://twitter.com/compose/tweet?text=I'm loving FastAPI because... https://github.com/tiangolo/fastapi cc @tiangolo" class="external-link" target="_blank">Tweet about **FastAPI**</a> and let me and others know why you like it. 🎉
I love to hear about how **FastAPI** is being used, what have you liked in it, in which project/company are you using it, etc.
You can let me know:
* <a href="https://twitter.com/compose/tweet?text=Hey @tiangolo, I'm using FastAPI at..." class="external-link" target="_blank">On **Twitter**</a>.
* <a href="https://www.linkedin.com/in/tiangolo/" class="external-link" target="_blank">On **Linkedin**</a>.
* <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">On **Medium**</a>.
## Vote for FastAPI
* <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.
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. 🤓
## 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>.
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>. 👀
If you select "Watching" instead of "Releases only", you will receive notifications when someone creates a new issue.
@@ -87,9 +70,10 @@ 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:
* Report a bug/issue.
* Ask a question or ask about a problem.
* Suggest a new feature.
* Ask a question.
**Note**: if you create an issue then I'm going to ask you to also help others. 😉
## Create a Pull Request
@@ -100,6 +84,39 @@ You can <a href="https://github.com/tiangolo/fastapi" class="external-link" targ
* 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 chat on Gitter: <a href="https://gitter.im/tiangolo/fastapi" class="external-link" target="_blank">https://gitter.im/tiangolo/fastapi</a>.
There you can have quick conversations with others, help others, share ideas, etc.
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.
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. 😅
Conversations in Gitter are also not as easily searchable as in GitHub, so questions and answers might get lost in the conversation.
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. 😄
## 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 😄.
## Sponsor the tools that power FastAPI
As you have seen in the documentation, FastAPI stands on the shoulders of giants, Starlette and Pydantic.
You can also sponsor:
* <a href="https://github.com/sponsors/samuelcolvin" class="external-link" target="_blank">Samuel Colvin (Pydantic)</a>
* <a href="https://github.com/sponsors/encode" class="external-link" target="_blank">Encode (Starlette, Uvicorn)</a>
---
Thanks!
Thanks! 🚀

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

@@ -0,0 +1,235 @@
<?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"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="63.5mm"
height="26.458334mm"
viewBox="0 0 63.5 26.458334"
version="1.1"
id="svg975"
inkscape:version="1.0.1 (1.0.1+r73)"
sodipodi:docname="testdriven.svg">
<defs
id="defs969">
<clipPath
id="clip0">
<rect
width="770"
height="222.03999"
fill="#ffffff"
id="rect14"
x="0"
y="0" />
</clipPath>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2"
inkscape:cx="133.05705"
inkscape:cy="115.91792"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
inkscape:document-rotation="0"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1025"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1" />
<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
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-75.455132,-135.96141)">
<rect
style="fill:#212529;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:#212529;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" />
<g
id="g1648"
transform="matrix(0.40937885,0,0,0.40937885,80.597548,138.01872)">
<path
d="M 1.6,4.62 3.2,5.54 11.19,0.92 9.59,0 Z m 9.59,-3.7 1.6,-0.92 8,4.62 -1.6,0.92 z m 9.6,5.54 -1.6,-0.92 -8,4.61 1.6,0.93 z m -9.6,3.69 -1.6,0.93 L 1.6,6.46 3.2,5.54 Z"
fill="#d2edf3"
id="path1538" />
<path
d="m 11.19,23.08 1.6,-0.93 v -9.23 l -1.6,0.93 z m 1.6,-10.16 v -1.84 l 8,-4.62 v 1.85 z m 9.59,-5.54 -1.59,0.93 -0.01,9.23 1.6,-0.93 z m -1.6,10.16 v 1.84 L 12.79,24 v -1.85 z"
fill="#76cede"
id="path1540" />
<path
d="m 11.19,23.08 -1.6,-0.93 v -9.23 l 1.6,0.93 z M 9.59,12.92 V 11.08 L 1.6,6.46 V 8.31 Z M 0,7.38 1.6,8.31 v 9.23 L 0,16.61 Z m 1.6,10.16 v 1.84 L 9.59,24 v -1.85 z"
fill="#339999"
id="path1542" />
<path
d="m 11.19,10.15 -1.6,0.93 v 1.84 L 11.19,12 Z"
fill="#76cede"
id="path1544" />
<path
d="m 9.59,12.92 1.6,0.93 1.6,-0.93 -1.6,-0.92 z"
fill="#d2edf3"
id="path1546" />
<path
d="M 11.19,10.15 V 12 l 1.6,0.92 v -1.84 z"
fill="#339999"
id="path1548" />
<path
d="m 20.78,17.54 -1.6,-0.92 -6.39,3.69 v 1.85 z m -19.18,0 1.6,-0.92 6.39,3.69 v 1.85 z"
fill="#d2edf3"
id="path1550" />
<path
d="m 1.6,8.31 1.6,0.92 v 7.38 l -1.6,0.93 z"
fill="#76cede"
id="path1552" />
<path
d="m 20.79,8.31 -1.6,0.92 v 7.38 l 1.59,0.93 z"
fill="#339999"
id="path1554" />
<path
d="M 11.19,0.92 V 2.77 L 4.8,6.46 3.2,5.54 Z"
fill="#76cede"
id="path1556" />
<path
d="m 11.19,0.92 v 1.85 l 6.39,3.69 1.61,-0.92 z"
fill="#339999"
id="path1558" />
<path
d="m 4.8,13.85 -1.6,0.92 v 1.84 l 1.6,-0.92 z"
fill="#d2edf3"
id="path1560" />
<path
d="M 3.2,16.61 4.8,17.54 6.4,16.61 4.8,15.69 Z"
fill="#76cede"
id="path1562" />
<path
d="m 4.8,13.85 v 1.84 l 1.6,0.92 v -1.84 z"
fill="#339999"
id="path1564" />
<path
d="m 9.59,5.54 1.6,0.92 1.6,-0.92 -1.6,-0.93 z"
fill="#d2edf3"
id="path1566" />
<path
d="M 12.79,5.54 V 3.69 l -1.6,-0.92 v 1.84 z"
fill="#76cede"
id="path1568" />
<path
d="m 9.59,5.54 1.6,-0.93 V 2.77 l -1.6,0.92 z"
fill="#339999"
id="path1570" />
<path
d="m 15.99,16.61 1.6,0.93 1.6,-0.93 -1.6,-0.92 z"
fill="#76cede"
id="path1572" />
<path
d="m 19.19,16.61 v -1.84 l -1.6,-0.92 v 1.84 z"
fill="#d2edf3"
id="path1574" />
<path
d="m 15.99,16.61 1.6,-0.92 v -1.84 l -1.6,0.92 z"
fill="#339999"
id="path1576" />
<path
d="M 9.59,12.92 6.4,14.77 v 1.84 l 3.19,-1.84 z"
fill="#76cede"
id="path1578" />
<path
d="M 9.59,12.92 6.4,14.77 4.8,13.85 8,12 Z"
fill="#d2edf3"
id="path1580" />
<path
d="M 11.19,10.15 V 6.46 L 9.59,5.54 v 3.69 z"
fill="#339999"
id="path1582" />
<path
d="M 11.19,10.15 V 6.46 l 1.6,-0.92 v 3.69 z m 1.6,2.77 3.2,1.85 v 1.84 l -3.2,-1.84 z"
fill="#76cede"
id="path1584" />
<path
d="m 12.79,12.92 3.2,1.85 1.6,-0.92 -3.2,-1.85 z"
fill="#d2edf3"
id="path1586" />
<path
d="M 11.19,23.07 12.79,24 V 22.15 M 3.2,5.54 1.6,4.62 v 1.84"
fill="#339999"
id="path1588" />
<path
d="M 11.19,23.07 9.59,24 v -1.85"
fill="#76cede"
id="path1590" />
<path
d="m 20.79,6.46 1.6,0.92 -1.6,0.92 M 1.6,8.3 0,7.38 1.6,6.46"
fill="#d2edf3"
id="path1592" />
<path
d="m 19.19,5.54 1.6,-0.92 v 1.84"
fill="#76cede"
id="path1594" />
<g
fill="#ffffff"
id="g1604">
<path
d="M 61.45,48.81 A 4.22,4.22 0 0 1 60.18,49 c -1.16,0 -1.5,-0.62 -1.5,-2.14 v -5.25 h 2.51 V 39.74 H 58.68 V 38.11 35 L 56,35.79 v 1.63 2.32 h -1.3 v 1.87 H 56 v 5.57 C 56,49.8 57.1,51 59.52,51 a 6.2,6.2 0 0 0 2.19,-0.34 z M 43.56,47.25 C 43.07,50.33 40.82,51 38.93,51 c -3.71,0 -5.17,-2.4 -5.17,-5.64 0,-3.62 2,-5.88 5.38,-5.88 3,0 4.55,1.87 4.55,5.08 0,0.36 0,0.82 -0.06,1.22 h -7.12 c 0,1.89 0.64,3.24 2.51,3.24 a 2.1,2.1 0 0 0 2.29,-2 z M 41.1,44 c 0.06,-1.72 -0.64,-2.7 -2.14,-2.7 -1.5,0 -2.36,1.27 -2.42,2.7 z M 71.58,35 V 51 H 70.26 V 49.16 A 3.77,3.77 0 0 1 66.88,51 c -2.64,0 -4.5,-1.54 -4.5,-5.55 0,-3.84 1.74,-5.92 4.65,-5.92 a 3.56,3.56 0 0 1 3.17,1.59 V 35 Z m -4.42,5.66 c -2.12,0 -3.32,1.57 -3.32,4.8 0,3.23 1.2,4.42 3.11,4.42 1.91,0 3.35,-1.16 3.35,-4.72 0,-3.56 -1.4,-4.5 -3.14,-4.5 z m 11.9,2.73 c 0.21,-2 -0.28,-2.42 -1.37,-2.42 -2,0 -2.72,1.87 -2.72,3.88 V 51 H 73.55 V 40 h 1.33 L 75,41.65 a 3.12,3.12 0 0 1 3,-1.87 c 1.69,0 2.77,1 2.38,3.54 z"
transform="translate(0,-31)"
id="path1596" />
<path
d="m 82.04,9.04 h 1.42 V 20 h -1.42 z m 0,-5.04 h 1.42 v 2.12 h -1.42 z"
id="path1598" />
<path
d="m 88.78,51 -3.9,-11 h 1.46 L 89.45,49.18 92.51,40 H 94 l -4,11 z m 14.3,-3.69 A 3.81,3.81 0 0 1 99,51 c -3.6,0 -4.74,-2.47 -4.74,-5.64 0,-3.47 1.67,-5.83 4.93,-5.83 2.9,0 4.33,2.19 3.92,6 H 95.7 c 0,2.3 0.75,4.29 3.28,4.29 a 2.7,2.7 0 0 0 2.94,-2.66 z m -1.22,-2.87 c 0.06,-2.14 -0.69,-3.77 -2.9,-3.77 -2.21,0 -3.22,1.87 -3.26,3.77 z M 113.33,51 h -1.42 v -6.37 c 0,-2.6 -0.86,-3.67 -2.66,-3.67 -2.55,0 -3.24,1.93 -3.24,3.73 V 51 H 104.6 V 40 h 1.33 l 0.09,1.67 a 3.63,3.63 0 0 1 3.41,-1.93 c 2.53,0 3.9,1.48 3.9,4.65 z M 51,43.09 a 1.76,1.76 0 0 0 -1.93,-1.76 c -1.09,0 -1.78,0.36 -1.78,1.22 0,2.4 6.18,0.39 6.18,4.85 0,2.34 -2.14,3.6 -4.63,3.6 -2.7,0 -4.25,-1.39 -4.62,-3.73 l 2.37,-0.19 a 2.13,2.13 0 0 0 2.29,2.07 c 1.35,0 2,-0.6 2,-1.39 0,-2.53 -6.11,-0.51 -6.11,-4.85 0,-2.25 1.93,-3.43 4.35,-3.43 2.42,0 3.84,1.07 4.23,3.11 z M 33.14,48.81 A 4.22,4.22 0 0 1 31.87,49 c -1.16,0 -1.5,-0.62 -1.5,-2.14 v -5.25 h 2.51 V 39.74 H 30.37 V 38.11 35 l -2.66,0.79 v 1.63 2.32 h -1.33 v 1.87 h 1.33 v 5.57 c 0,2.62 1.07,3.82 3.5,3.82 a 6.2,6.2 0 0 0 2.19,-0.34 z m 87.47,-3.43 c 0,-3.67 2.08,-5.6 4.88,-5.6 2.8,0 4.5,1.89 4.5,5.39 C 130,49 128.26,51 125.26,51 c -3.18,0 -4.65,-2 -4.65,-5.62 z m 8,-0.08 c 0,-2.47 -0.88,-4.36 -3.22,-4.36 -2.34,0 -3.32,2 -3.32,4.42 0,2.42 0.84,4.51 3.28,4.51 2.44,0 3.23,-2.04 3.23,-4.57 z"
transform="translate(0,-31)"
id="path1600" />
<path
d="m 114.88,17.88 h 1.42 V 20 h -1.42 z m 2.86,-8.84 h 1.42 V 20 h -1.42 z m 0,-5.04 h 1.42 v 2.12 h -1.42 z"
id="path1602" />
</g>
</g>
<text
xml:space="preserve"
style="font-size:4.23333px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;stroke-width:0.133861"
x="107.5555"
y="154.45795"
id="text1712"><tspan
sodipodi:role="line"
id="tspan1710"
x="107.5555"
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:#ffffff;stroke-width:0.133861">Learn Test-Driven Development </tspan><tspan
sodipodi:role="line"
x="107.5555"
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:#ffffff;stroke-width:0.133861"
id="tspan2004">with FastAPI</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.9 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 71 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 116 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 88 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 82 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 80 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 87 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 76 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View File

@@ -5,14 +5,14 @@
<em>FastAPI framework, high performance, easy to learn, fast to code, ready for production</em>
</p>
<p align="center">
<a href="https://travis-ci.com/tiangolo/fastapi" target="_blank">
<img src="https://travis-ci.com/tiangolo/fastapi.svg?branch=master" alt="Build Status">
<a href="https://github.com/tiangolo/fastapi/actions?query=workflow%3ATest" target="_blank">
<img src="https://github.com/tiangolo/fastapi/workflows/Test/badge.svg" alt="Test">
</a>
<a href="https://codecov.io/gh/tiangolo/fastapi" target="_blank">
<img src="https://img.shields.io/codecov/c/github/tiangolo/fastapi" alt="Coverage">
<img src="https://img.shields.io/codecov/c/github/tiangolo/fastapi?color=%2334D058" alt="Coverage">
</a>
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://badge.fury.io/py/fastapi.svg" alt="Package version">
<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">
@@ -33,50 +33,70 @@ The key features are:
* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
* **Fast to code**: Increase the speed to develop features by about 200% to 300% *.
* **Fast to code**: Increase the speed to develop features by about 200% to 300%. *
* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. *
* **Intuitive**: Great editor support. <abbr title="also known as auto-complete, autocompletion, IntelliSense">Completion</abbr> everywhere. Less time debugging.
* **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.*"
"_[...] 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._"
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/tiangolo/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div>
---
"*Im over the moon excited about **FastAPI**. Its so fun!*"
"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_"
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div>
---
"_**Netflix** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_"
<div style="text-align: right; margin-right: 10%;">Kevin Glisson, Marc Vilanova, Forest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072" target="_blank"><small>(ref)</small></a></div>
---
"_Im over the moon excited about **FastAPI**. Its so fun!_"
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a> podcast host</strong> <a href="https://twitter.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
---
"*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.*"
"_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>
---
"*If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]*"
"_If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]_"
"*We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]*"
"_We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]_"
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> founders - <a href="https://spacy.io" target="_blank">spaCy</a> creators</strong> <a href="https://twitter.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://twitter.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
---
"*We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]*"
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div>
---
## **Typer**, the FastAPI of CLIs
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
@@ -106,7 +126,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">
@@ -125,6 +145,8 @@ $ pip install uvicorn
* Create a file `main.py` with:
```Python
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@@ -136,7 +158,7 @@ def read_root():
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "q": q}
```
@@ -145,7 +167,9 @@ def read_item(item_id: int, q: str = None):
If your code uses `async` / `await`, use `async def`:
```Python hl_lines="7 12"
```Python hl_lines="9 14"
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@@ -157,7 +181,7 @@ async def read_root():
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str = None):
async def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "q": q}
```
@@ -235,7 +259,9 @@ 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="2 7 8 9 10 23 24 25"
```Python hl_lines="4 9-12 25-27"
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
@@ -245,7 +271,7 @@ app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: bool = None
is_offer: Optional[bool] = None
@app.get("/")
@@ -254,7 +280,7 @@ def read_root():
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "q": q}
@@ -416,9 +442,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).
@@ -427,7 +453,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.
@@ -69,3 +69,16 @@ You can read more about it in the docs for the repo.
## Full Stack FastAPI MongoDB
...might come later, depending on my time availability and other factors. 😅 🎉
## Machine Learning models with spaCy and FastAPI
GitHub: <a href="https://github.com/microsoft/cookiecutter-spacy-fastapi" class="external-link" target="_blank">https://github.com/microsoft/cookiecutter-spacy-fastapi</a>
### Machine Learning models with spaCy and FastAPI - Features
* **spaCy** NER model integration.
* **Azure Cognitive Search** request format built in.
* **Production ready** Python web server using Uvicorn and Gunicorn.
* **Azure DevOps** Kubernetes (AKS) CI/CD deployment built in.
* **Multilingual** Easily choose one of spaCy's built in languages during project setup.
* **Easily extensible** to other model frameworks (Pytorch, Tensorflow), not just spaCy.

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.
@@ -144,15 +144,15 @@ You can use, for example:
{!../../../docs_src/python_types/tutorial005.py!}
```
### Types with subtypes
### Generic types with type parameters
There are some data structures that can contain other values, like `dict`, `list`, `set` and `tuple`. And the internal values can have their own type too.
To declare those types and the subtypes, you can use the standard Python module `typing`.
To declare those types and the internal types, you can use the standard Python module `typing`.
It exists specifically to support these type hints.
#### Lists
#### `List`
For example, let's define a variable to be a `list` of `str`.
@@ -166,29 +166,34 @@ Declare the variable, with the same colon (`:`) syntax.
As the type, put the `List`.
As the list is a type that takes a "subtype", you put the subtype in square brackets:
As the list is a type that contains some internal types, you put them in square brackets:
```Python hl_lines="4"
{!../../../docs_src/python_types/tutorial006.py!}
```
!!! tip
Those internal types in the square brackets are called "type parameters".
In this case, `str` is the type parameter passed to `List`.
That means: "the variable `items` is a `list`, and each of the items in this list is a `str`".
By doing that, your editor can provide support even while processing items from the list.
Without types, that's almost impossible to achieve:
By doing that, your editor can provide support even while processing items from the list:
<img src="/img/python-types/image05.png">
Without types, that's almost impossible to achieve.
Notice that the variable `item` is one of the elements in the list `items`.
And still, the editor knows it is a `str`, and provides support for that.
#### Tuples and Sets
#### `Tuple` and `Set`
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!}
```
@@ -197,15 +202,15 @@ This means:
* The variable `items_t` is a `tuple` with 3 items, an `int`, another `int`, and a `str`.
* The variable `items_s` is a `set`, and each of its items is of type `bytes`.
#### Dicts
#### `Dict`
To define a `dict`, you pass 2 subtypes, separated by commas.
To define a `dict`, you pass 2 type parameters, separated by commas.
The first subtype is for the keys of the `dict`.
The first type parameter is for the keys of the `dict`.
The second subtype is for the values 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!}
```
@@ -215,20 +220,43 @@ This means:
* The keys of this `dict` are of type `str` (let's say, the name of each item).
* The values of this `dict` are of type `float` (let's say, the price of each item).
#### `Optional`
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"
{!../../../docs_src/python_types/tutorial009.py!}
```
Using `Optional[str]` instead of just `str` will let the editor help you detecting errors where you could be assuming that a value is always a `str`, when it could actually be `None` too.
#### Generic types
These types that take type parameters in square brackets, like:
* `List`
* `Tuple`
* `Set`
* `Dict`
* `Optional`
* ...and others.
are called **Generic types** or **Generics**.
### Classes as types
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"
{!../../../docs_src/python_types/tutorial009.py!}
```Python hl_lines="1-3"
{!../../../docs_src/python_types/tutorial010.py!}
```
Then you can declare a variable to be of type `Person`:
```Python hl_lines="6"
{!../../../docs_src/python_types/tutorial009.py!}
{!../../../docs_src/python_types/tutorial010.py!}
```
And then, again, you get all the editor support:
@@ -250,7 +278,7 @@ And you get all the editor support with that resulting object.
Taken from the official Pydantic docs:
```Python
{!../../../docs_src/python_types/tutorial010.py!}
{!../../../docs_src/python_types/tutorial011.py!}
```
!!! info

View File

@@ -1,6 +1,325 @@
# Release Notes
## Latest changes
## Latest Changes
* 📝 Fix image links for sponsors. PR [#2304](https://github.com/tiangolo/fastapi/pull/2304) 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
* Fix typo in docs for query parameters. PR [#1832](https://github.com/tiangolo/fastapi/pull/1832) by [@ycd](https://github.com/ycd).
* Add docs about [Async Tests](https://fastapi.tiangolo.com/advanced/async-tests/). PR [#1619](https://github.com/tiangolo/fastapi/pull/1619) by [@empicano](https://github.com/empicano).
* Raise an exception when using form data (`Form`, `File`) without having `python-multipart` installed.
* Up to now the application would run, and raise an exception only when receiving a request with form data, the new behavior, raising early, will prevent from deploying applications with broken dependencies.
* It also detects if the correct package `python-multipart` is installed instead of the incorrect `multipart` (both importable as `multipart`).
* PR [#1851](https://github.com/tiangolo/fastapi/pull/1851) based on original PR [#1627](https://github.com/tiangolo/fastapi/pull/1627) by [@chrisngyn](https://github.com/chrisngyn), [@YKo20010](https://github.com/YKo20010), [@kx-chen](https://github.com/kx-chen).
* Re-enable Gitter releases bot. PR [#1831](https://github.com/tiangolo/fastapi/pull/1831).
* Add link to async SQL databases tutorial from main SQL tutorial. PR [#1813](https://github.com/tiangolo/fastapi/pull/1813) by [@short2strings](https://github.com/short2strings).
* Fix typo in tutorial about behind a proxy. PR [#1807](https://github.com/tiangolo/fastapi/pull/1807) by [@toidi](https://github.com/toidi).
* Fix typo in Portuguese docs. PR [#1795](https://github.com/tiangolo/fastapi/pull/1795) by [@izaguerreiro](https://github.com/izaguerreiro).
* Add translations setup for Ukrainian. PR [#1830](https://github.com/tiangolo/fastapi/pull/1830).
* Add external link [Build And Host Fast Data Science Applications Using FastAPI](https://towardsdatascience.com/build-and-host-fast-data-science-applications-using-fastapi-823be8a1d6a0). PR [#1786](https://github.com/tiangolo/fastapi/pull/1786) by [@Kludex](https://github.com/Kludex).
* Fix encoding of Pydantic models that inherit from others models with custom `json_encoders`. PR [#1769](https://github.com/tiangolo/fastapi/pull/1769) by [@henrybetts](https://github.com/henrybetts).
* Simplify and improve `jsonable_encoder`. PR [#1754](https://github.com/tiangolo/fastapi/pull/1754) by [@MashhadiNima](https://github.com/MashhadiNima).
* Simplify internal code syntax in several points. PR [#1753](https://github.com/tiangolo/fastapi/pull/1753) by [@uriyyo](https://github.com/uriyyo).
* Improve internal typing, declare `Optional` parameters. PR [#1731](https://github.com/tiangolo/fastapi/pull/1731) by [@MashhadiNima](https://github.com/MashhadiNima).
* Add external link [Deploy FastAPI on Azure App Service](https://www.tutlinks.com/deploy-fastapi-on-azure/) to docs. PR [#1726](https://github.com/tiangolo/fastapi/pull/1726) by [@windson](https://github.com/windson).
* Add link to Starlette docs about WebSocket testing. PR [#1717](https://github.com/tiangolo/fastapi/pull/1717) by [@hellocoldworld](https://github.com/hellocoldworld).
* Refactor generating dependant, merge for loops. PR [#1714](https://github.com/tiangolo/fastapi/pull/1714) by [@Bloodielie](https://github.com/Bloodielie).
* Update example for templates with Jinja to include HTML media type. PR [#1690](https://github.com/tiangolo/fastapi/pull/1690) by [@frafra](https://github.com/frafra).
* Fix typos in docs for security. PR [#1678](https://github.com/tiangolo/fastapi/pull/1678) by [@nilslindemann](https://github.com/nilslindemann).
* Fix typos in docs for dependencies. PR [#1675](https://github.com/tiangolo/fastapi/pull/1675) by [@nilslindemann](https://github.com/nilslindemann).
* Fix type annotation for `**extra` parameters in `FastAPI`. PR [#1659](https://github.com/tiangolo/fastapi/pull/1659) by [@bharel](https://github.com/bharel).
* Bump MkDocs Material to fix docs in browsers with dark mode. PR [#1789](https://github.com/tiangolo/fastapi/pull/1789) by [@adriencaccia](https://github.com/adriencaccia).
* Remove docs preview comment from each commit. PR [#1826](https://github.com/tiangolo/fastapi/pull/1826).
* Update GitHub context extraction for Gitter notification bot. PR [#1766](https://github.com/tiangolo/fastapi/pull/1766).
## 0.60.1
* Add debugging logs for GitHub actions to introspect GitHub hidden context. PR [#1764](https://github.com/tiangolo/fastapi/pull/1764).
* Use OS preference theme for online docs. PR [#1760](https://github.com/tiangolo/fastapi/pull/1760) by [@adriencaccia](https://github.com/adriencaccia).
* Upgrade Starlette to version `0.13.6` to handle a vulnerability when using static files in Windows. PR [#1759](https://github.com/tiangolo/fastapi/pull/1759) by [@jamesag26](https://github.com/jamesag26).
* Pin Swagger UI temporarily, waiting for a fix for [swagger-api/swagger-ui#6249](https://github.com/swagger-api/swagger-ui/issues/6249). PR [#1763](https://github.com/tiangolo/fastapi/pull/1763).
* Update GitHub Actions, use commit from PR for docs preview, not commit from pre-merge. PR [#1761](https://github.com/tiangolo/fastapi/pull/1761).
* Update GitHub Actions, refactor Gitter bot. PR [#1746](https://github.com/tiangolo/fastapi/pull/1746).
## 0.60.0
* Add GitHub Action to watch for missing preview docs and trigger a preview deploy. PR [#1740](https://github.com/tiangolo/fastapi/pull/1740).
* Add custom GitHub Action to get artifact with docs preview. PR [#1739](https://github.com/tiangolo/fastapi/pull/1739).
* Add new GitHub Actions to preview docs from PRs. PR [#1738](https://github.com/tiangolo/fastapi/pull/1738).
* Add XML test coverage to support GitHub Actions. PR [#1737](https://github.com/tiangolo/fastapi/pull/1737).
* Update badges and remove Travis now that GitHub Actions is the main CI. PR [#1736](https://github.com/tiangolo/fastapi/pull/1736).
* Add GitHub Actions for CI, move from Travis. PR [#1735](https://github.com/tiangolo/fastapi/pull/1735).
* Add support for adding OpenAPI schema for GET requests with a body. PR [#1626](https://github.com/tiangolo/fastapi/pull/1626) by [@victorphoenix3](https://github.com/victorphoenix3).
## 0.59.0
* Fix typo in docstring for OAuth2 utils. PR [#1621](https://github.com/tiangolo/fastapi/pull/1621) by [@tomarv2](https://github.com/tomarv2).
* Update JWT docs to use Python-jose instead of PyJWT. Initial PR [#1610](https://github.com/tiangolo/fastapi/pull/1610) by [@asheux](https://github.com/asheux).
* Fix/re-enable search bar in docs. PR [#1703](https://github.com/tiangolo/fastapi/pull/1703).
* Auto-generate a "server" in OpenAPI `servers` when there's a `root_path` instead of prefixing all the `paths`:
* Add a new parameter for `FastAPI` classes: `root_path_in_servers` to disable the auto-generation of `servers`.
* New docs about `root_path` and `servers` in [Additional Servers](https://fastapi.tiangolo.com/advanced/behind-a-proxy/#additional-servers).
* Update OAuth2 examples to use a relative URL for `tokenUrl="token"` to make sure those examples keep working as-is even when behind a reverse proxy.
* Initial PR [#1596](https://github.com/tiangolo/fastapi/pull/1596) by [@rkbeatss](https://github.com/rkbeatss).
* Fix typo/link in External Links. PR [#1702](https://github.com/tiangolo/fastapi/pull/1702).
* Update handling of [External Links](https://fastapi.tiangolo.com/external-links/) to use a data file and allow translating the headers without becoming obsolete quickly when new links are added. PR [#https://github.com/tiangolo/fastapi/pull/1701](https://github.com/tiangolo/fastapi/pull/1701).
* Add external link [Machine learning model serving in Python using FastAPI and Streamlit](https://davidefiocco.github.io/2020/06/27/streamlit-fastapi-ml-serving.html) to docs. PR [#1669](https://github.com/tiangolo/fastapi/pull/1669) by [@davidefiocco](https://github.com/davidefiocco).
* Add note in docs on order in Pydantic Unions. PR [#1591](https://github.com/tiangolo/fastapi/pull/1591) by [@kbanc](https://github.com/kbanc).
* Improve support for tests in editor. PR [#1699](https://github.com/tiangolo/fastapi/pull/1699).
* Pin dependencies. PR [#1697](https://github.com/tiangolo/fastapi/pull/1697).
* Update isort to version 5.x.x. PR [#1670](https://github.com/tiangolo/fastapi/pull/1670) by [@asheux](https://github.com/asheux).
## 0.58.1
* Add link in docs to Pydantic data types. PR [#1612](https://github.com/tiangolo/fastapi/pull/1612) by [@tayoogunbiyi](https://github.com/tayoogunbiyi).
* Fix link in warning logs for `openapi_prefix`. PR [#1611](https://github.com/tiangolo/fastapi/pull/1611) by [@bavaria95](https://github.com/bavaria95).
* Fix bad link in docs. PR [#1603](https://github.com/tiangolo/fastapi/pull/1603) by [@molto0504](https://github.com/molto0504).
* Add Vim temporary files to `.gitignore` for contributors using Vim. PR [#1590](https://github.com/tiangolo/fastapi/pull/1590) by [@asheux](https://github.com/asheux).
* Fix typo in docs for sub-applications. PR [#1578](https://github.com/tiangolo/fastapi/pull/1578) by [@schlpbch](https://github.com/schlpbch).
* Use `Optional` in all the examples in the docs. Original PR [#1574](https://github.com/tiangolo/fastapi/pull/1574) by [@chrisngyn](https://github.com/chrisngyn), [@kx-chen](https://github.com/kx-chen), [@YKo20010](https://github.com/YKo20010). Updated and merged PR [#1644](https://github.com/tiangolo/fastapi/pull/1644).
* Update tests and handling of `response_model_by_alias`. PR [#1642](https://github.com/tiangolo/fastapi/pull/1642).
* Add translation to Chinese for [Body - Fields - 请求体 - 字段](https://fastapi.tiangolo.com/zh/tutorial/body-fields/). PR [#1569](https://github.com/tiangolo/fastapi/pull/1569) by [@waynerv](https://github.com/waynerv).
* Update Chinese translation of main page. PR [#1564](https://github.com/tiangolo/fastapi/pull/1564) by [@waynerv](https://github.com/waynerv).
* Add translation to Chinese for [Body - Multiple Parameters - 请求体 - 多个参数](https://fastapi.tiangolo.com/zh/tutorial/body-multiple-params/). PR [#1532](https://github.com/tiangolo/fastapi/pull/1532) by [@waynerv](https://github.com/waynerv).
* Add translation to Chinese for [Path Parameters and Numeric Validations - 路径参数和数值校验](https://fastapi.tiangolo.com/zh/tutorial/path-params-numeric-validations/). PR [#1506](https://github.com/tiangolo/fastapi/pull/1506) by [@waynerv](https://github.com/waynerv).
* Add GitHub action to auto-label approved PRs (mainly for translations). PR [#1638](https://github.com/tiangolo/fastapi/pull/1638).
## 0.58.0
* Deep merge OpenAPI responses to preserve all the additional metadata. PR [#1577](https://github.com/tiangolo/fastapi/pull/1577).
* Mention in docs that only main app events are run (not sub-apps). PR [#1554](https://github.com/tiangolo/fastapi/pull/1554) by [@amacfie](https://github.com/amacfie).
* Fix body validation error response, do not include body variable when it is not embedded. PR [#1553](https://github.com/tiangolo/fastapi/pull/1553) by [@amacfie](https://github.com/amacfie).
* Fix testing OAuth2 security scopes when using dependency overrides. PR [#1549](https://github.com/tiangolo/fastapi/pull/1549) by [@amacfie](https://github.com/amacfie).
* Fix Model for JSON Schema keyword `not` as a JSON Schema instead of a list. PR [#1548](https://github.com/tiangolo/fastapi/pull/1548) by [@v-do](https://github.com/v-do).
* Add support for OpenAPI `servers`. PR [#1547](https://github.com/tiangolo/fastapi/pull/1547) by [@mikaello](https://github.com/mikaello).
## 0.57.0
* Remove broken link from "External Links". PR [#1565](https://github.com/tiangolo/fastapi/pull/1565) by [@victorphoenix3](https://github.com/victorphoenix3).
* Update/fix docs for [WebSockets with dependencies](https://fastapi.tiangolo.com/advanced/websockets/#using-depends-and-others). Original PR [#1540](https://github.com/tiangolo/fastapi/pull/1540) by [@ChihSeanHsu](https://github.com/ChihSeanHsu).
* Add support for Python's `http.HTTPStatus` in `status_code` parameters. PR [#1534](https://github.com/tiangolo/fastapi/pull/1534) by [@retnikt](https://github.com/retnikt).
* When using Pydantic models with `__root__`, use the internal value in `jsonable_encoder`. PR [#1524](https://github.com/tiangolo/fastapi/pull/1524) by [@patrickkwang](https://github.com/patrickkwang).
* Update docs for path parameters. PR [#1521](https://github.com/tiangolo/fastapi/pull/1521) by [@yankeexe](https://github.com/yankeexe).
* Update docs for first steps, links and rewording. PR [#1518](https://github.com/tiangolo/fastapi/pull/1518) by [@yankeexe](https://github.com/yankeexe).
* Enable `showCommonExtensions` in Swagger UI to show additional validations like `maxLength`, etc. PR [#1466](https://github.com/tiangolo/fastapi/pull/1466) by [@TiewKH](https://github.com/TiewKH).
* Make `OAuth2PasswordRequestFormStrict` importable directly from `fastapi.security`. PR [#1462](https://github.com/tiangolo/fastapi/pull/1462) by [@RichardHoekstra](https://github.com/RichardHoekstra).
* Add docs about [Default response class](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class). PR [#1455](https://github.com/tiangolo/fastapi/pull/1455) by [@TezRomacH](https://github.com/TezRomacH).
* Add note in docs about additional parameters `response_model_exclude_defaults` and `response_model_exclude_none` in [Response Model](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). PR [#1427](https://github.com/tiangolo/fastapi/pull/1427) by [@wshayes](https://github.com/wshayes).
* Add note about [PyCharm Pydantic plugin](https://github.com/koxudaxi/pydantic-pycharm-plugin) to docs. PR [#1420](https://github.com/tiangolo/fastapi/pull/1420) by [@koxudaxi](https://github.com/koxudaxi).
* Update and clarify testing function name. PR [#1395](https://github.com/tiangolo/fastapi/pull/1395) by [@chenl](https://github.com/chenl).
* Fix duplicated headers created by indirect dependencies that use the request directly. PR [#1386](https://github.com/tiangolo/fastapi/pull/1386) by [@obataku](https://github.com/obataku) from tests by [@scottsmith2gmail](https://github.com/scottsmith2gmail).
* Upgrade Starlette version to `0.13.4`. PR [#1361](https://github.com/tiangolo/fastapi/pull/1361) by [@rushton](https://github.com/rushton).
* Improve error handling and feedback for requests with invalid JSON. PR [#1354](https://github.com/tiangolo/fastapi/pull/1354) by [@aviramha](https://github.com/aviramha).
* Add support for declaring metadata for tags in OpenAPI. New docs at [Tutorial - Metadata and Docs URLs - Metadata for tags](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-tags). PR [#1348](https://github.com/tiangolo/fastapi/pull/1348) by [@thomas-maschler](https://github.com/thomas-maschler).
* Add basic setup for Russian translations. PR [#1566](https://github.com/tiangolo/fastapi/pull/1566).
* Remove obsolete Chinese articles after adding official community translations. PR [#1510](https://github.com/tiangolo/fastapi/pull/1510) by [@waynerv](https://github.com/waynerv).
* Add `__repr__` for *path operation function* parameter helpers (like `Query`, `Depends`, etc) to simplify debugging. PR [#1560](https://github.com/tiangolo/fastapi/pull/1560) by [@rkbeatss](https://github.com/rkbeatss) and [@victorphoenix3](https://github.com/victorphoenix3).
## 0.56.1
* Add link to advanced docs from tutorial. PR [#1512](https://github.com/tiangolo/fastapi/pull/1512) by [@kx-chen](https://github.com/kx-chen).
* Remove internal unnecessary f-strings. PR [#1526](https://github.com/tiangolo/fastapi/pull/1526) by [@kotamatsuoka](https://github.com/kotamatsuoka).
* Add translation to Chinese for [Query Parameters and String Validations - 查询参数和字符串校验](https://fastapi.tiangolo.com/zh/tutorial/query-params-str-validations/). PR [#1500](https://github.com/tiangolo/fastapi/pull/1500) by [@waynerv](https://github.com/waynerv).
* Add translation to Chinese for [Request Body - 请求体](https://fastapi.tiangolo.com/zh/tutorial/body/). PR [#1492](https://github.com/tiangolo/fastapi/pull/1492) by [@waynerv](https://github.com/waynerv).
* Add translation to Chinese for [Help FastAPI - Get Help - 帮助 FastAPI - 获取帮助](https://fastapi.tiangolo.com/zh/help-fastapi/). PR [#1465](https://github.com/tiangolo/fastapi/pull/1465) by [@waynerv](https://github.com/waynerv).
* Add translation to Chinese for [Query Parameters - 查询参数](https://fastapi.tiangolo.com/zh/tutorial/query-params/). PR [#1454](https://github.com/tiangolo/fastapi/pull/1454) by [@waynerv](https://github.com/waynerv).
* Add translation to Chinese for [Contributing - 开发 - 贡献](https://fastapi.tiangolo.com/zh/contributing/). PR [#1460](https://github.com/tiangolo/fastapi/pull/1460) by [@waynerv](https://github.com/waynerv).
* Add translation to Chinese for [Path Parameters - 路径参数](https://fastapi.tiangolo.com/zh/tutorial/path-params/). PR [#1453](https://github.com/tiangolo/fastapi/pull/1453) by [@waynerv](https://github.com/waynerv).
* Add official Microsoft project generator for [serving spaCy with FastAPI and Azure Cognitive Skills](https://github.com/microsoft/cookiecutter-spacy-fastapi) to [Project Generators](https://fastapi.tiangolo.com/project-generation/). PR [#1390](https://github.com/tiangolo/fastapi/pull/1390) by [@kabirkhan](https://github.com/kabirkhan).
* Update docs in [Python Types Intro](https://fastapi.tiangolo.com/python-types/) to include info about `Optional`. Original PR [#1377](https://github.com/tiangolo/fastapi/pull/1377) by [@yaegassy](https://github.com/yaegassy).
* Fix support for callable class dependencies with `yield`. PR [#1365](https://github.com/tiangolo/fastapi/pull/1365) by [@mrosales](https://github.com/mrosales).
* Fix/remove incorrect error logging when a client sends invalid payloads. PR [#1351](https://github.com/tiangolo/fastapi/pull/1351) by [@dbanty](https://github.com/dbanty).
* Add translation to Chinese for [First Steps - 第一步](https://fastapi.tiangolo.com/zh/tutorial/first-steps/). PR [#1323](https://github.com/tiangolo/fastapi/pull/1323) by [@waynerv](https://github.com/waynerv).
* Fix generating OpenAPI for apps using callbacks with routers including Pydantic models. PR [#1322](https://github.com/tiangolo/fastapi/pull/1322) by [@nsidnev](https://github.com/nsidnev).
* Optimize internal regex performance in `get_path_param_names()`. PR [#1243](https://github.com/tiangolo/fastapi/pull/1243) by [@heckad](https://github.com/heckad).
* Remove `*,` from functions in docs where it's not needed. PR [#1239](https://github.com/tiangolo/fastapi/pull/1239) by [@pankaj-giri](https://github.com/pankaj-giri).
* Start translations for Italian. PR [#1557](https://github.com/tiangolo/fastapi/pull/1557) by [@csr](https://github.com/csr).
## 0.56.0
* Add support for ASGI `root_path`:
* Use `root_path` internally for mounted applications, so that OpenAPI and the docs UI works automatically without extra configurations and parameters.
* Add new `root_path` parameter for `FastAPI` applications to provide it in cases where it can be set with the command line (e.g. for Uvicorn and Hypercorn, with the parameter `--root-path`).
* Deprecate `openapi_prefix` parameter in favor of the new `root_path` parameter.
* Add new/updated docs for [Sub Applications - Mounts](https://fastapi.tiangolo.com/advanced/sub-applications/), without `openapi_prefix` (as it is now handled automatically).
* Add new/updated docs for [Behind a Proxy](https://fastapi.tiangolo.com/advanced/behind-a-proxy/), including how to setup a local testing proxy with Traefik and using `root_path`.
* Update docs for [Extending OpenAPI](https://fastapi.tiangolo.com/advanced/extending-openapi/) with the new `openapi_prefix` parameter passed (internally generated from `root_path`).
* Original PR [#1199](https://github.com/tiangolo/fastapi/pull/1199) by [@iksteen](https://github.com/iksteen).
* Update new issue templates and docs: [Help FastAPI - Get Help](https://fastapi.tiangolo.com/help-fastapi/). PR [#1531](https://github.com/tiangolo/fastapi/pull/1531).
* Update GitHub action issue-manager. PR [#1520](https://github.com/tiangolo/fastapi/pull/1520).
* Add new links:
* **English articles**:
* [Real-time Notifications with Python and Postgres](https://wuilly.com/2019/10/real-time-notifications-with-python-and-postgres/) by [Guillermo Cruz](https://wuilly.com/).
* [Microservice in Python using FastAPI](https://dev.to/paurakhsharma/microservice-in-python-using-fastapi-24cc) by [Paurakh Sharma Humagain](https://twitter.com/PaurakhSharma).
* [Build simple API service with Python FastAPI — Part 1](https://dev.to/cuongld2/build-simple-api-service-with-python-fastapi-part-1-581o) by [cuongld2](https://dev.to/cuongld2).
* [FastAPI + Zeit.co = 🚀](https://paulsec.github.io/posts/fastapi_plus_zeit_serverless_fu/) by [Paul Sec](https://twitter.com/PaulWebSec).
* [Build a web API from scratch with FastAPI - the workshop](https://dev.to/tiangolo/build-a-web-api-from-scratch-with-fastapi-the-workshop-2ehe) by [Sebastián Ramírez (tiangolo)](https://twitter.com/tiangolo).
* [Build a Secure Twilio Webhook with Python and FastAPI](https://www.twilio.com/blog/build-secure-twilio-webhook-python-fastapi) by [Twilio](https://www.twilio.com).
* [Using FastAPI with Django](https://www.stavros.io/posts/fastapi-with-django/) by [Stavros Korokithakis](https://twitter.com/Stavros).
* [Introducing Dispatch](https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072) by [Netflix](https://netflixtechblog.com/).
* **Podcasts**:
* [Build The Next Generation Of Python Web Applications With FastAPI - Episode 259 - interview to Sebastían Ramírez (tiangolo)](https://www.pythonpodcast.com/fastapi-web-application-framework-episode-259/) by [Podcast.`__init__`](https://www.pythonpodcast.com/).
* **Talks**:
* [PyConBY 2020: Serve ML models easily with FastAPI](https://www.youtube.com/watch?v=z9K5pwb0rt8) by [Sebastián Ramírez (tiangolo)](https://twitter.com/tiangolo).
* [[VIRTUAL] Py.Amsterdam's flying Software Circus: Intro to FastAPI](https://www.youtube.com/watch?v=PnpTY1f4k2U) by [Sebastián Ramírez (tiangolo)](https://twitter.com/tiangolo).
* PR [#1467](https://github.com/tiangolo/fastapi/pull/1467).
* Add translation to Chinese for [Python Types Intro - Python 类型提示简介](https://fastapi.tiangolo.com/zh/python-types/). PR [#1197](https://github.com/tiangolo/fastapi/pull/1197) by [@waynerv](https://github.com/waynerv).
## 0.55.1
* Fix handling of enums with their own schema in path parameters. To support [samuelcolvin/pydantic#1432](https://github.com/samuelcolvin/pydantic/pull/1432) in FastAPI. PR [#1463](https://github.com/tiangolo/fastapi/pull/1463).
## 0.55.0
* Allow enums to allow them to have their own schemas in OpenAPI. To support [samuelcolvin/pydantic#1432](https://github.com/samuelcolvin/pydantic/pull/1432) in FastAPI. PR [#1461](https://github.com/tiangolo/fastapi/pull/1461).
* Add links for funding through [GitHub sponsors](https://github.com/sponsors/tiangolo). PR [#1425](https://github.com/tiangolo/fastapi/pull/1425).
* Update issue template for for questions. PR [#1344](https://github.com/tiangolo/fastapi/pull/1344) by [@retnikt](https://github.com/retnikt).
* Update warning about storing passwords in docs. PR [#1336](https://github.com/tiangolo/fastapi/pull/1336) by [@skorokithakis](https://github.com/skorokithakis).
* Fix typo. PR [#1326](https://github.com/tiangolo/fastapi/pull/1326) by [@chenl](https://github.com/chenl).
* Add translation to Portuguese for [Alternatives, Inspiration and Comparisons - Alternativas, Inspiração e Comparações](https://fastapi.tiangolo.com/pt/alternatives/). PR [#1325](https://github.com/tiangolo/fastapi/pull/1325) by [@Serrones](https://github.com/Serrones).
* Fix 2 typos in docs. PR [#1324](https://github.com/tiangolo/fastapi/pull/1324) by [@waynerv](https://github.com/waynerv).
* Update CORS docs, fix correct default of `max_age=600`. PR [#1301](https://github.com/tiangolo/fastapi/pull/1301) by [@derekbekoe](https://github.com/derekbekoe).
* Add translation of [main page to Portuguese](https://fastapi.tiangolo.com/pt/). PR [#1300](https://github.com/tiangolo/fastapi/pull/1300) by [@Serrones](https://github.com/Serrones).
* Re-word and clarify docs for extra info in fields. PR [#1299](https://github.com/tiangolo/fastapi/pull/1299) by [@chris-allnutt](https://github.com/chris-allnutt).
* Make sure the `*` in short features in the docs is consistent (after `.`) in all languages. PR [#1424](https://github.com/tiangolo/fastapi/pull/1424).
* Update order of execution for `get_db` in SQLAlchemy tutorial. PR [#1293](https://github.com/tiangolo/fastapi/pull/1293) by [@bcb](https://github.com/bcb).
* Fix typos in Async docs. PR [#1423](https://github.com/tiangolo/fastapi/pull/1423).
## 0.54.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="11 14 20 23"
```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

@@ -60,7 +60,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 +70,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!}
```
@@ -83,7 +83,7 @@ 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 add another `APIRouter`.
## Another module with `APIRouter`
@@ -100,7 +100,7 @@ But let's say that this time we are more lazy.
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):
```Python hl_lines="6 11"
```Python hl_lines="6 11"
{!../../../docs_src/bigger_applications/app/routers/items.py!}
```
@@ -110,7 +110,7 @@ We are not adding the prefix `/items/` nor the `tags=["items"]` to add them late
But we can add custom `tags` and `responses` that will be applied to a specific *path operation*:
```Python hl_lines="18 19"
```Python hl_lines="18-19"
{!../../../docs_src/bigger_applications/app/routers/items.py!}
```
@@ -126,7 +126,7 @@ This will be the main file in your application that ties everything together.
You import and create a `FastAPI` class as normally:
```Python hl_lines="1 5"
```Python hl_lines="1 5"
{!../../../docs_src/bigger_applications/app/main.py!}
```
@@ -245,7 +245,7 @@ And we can add predefined `responses` that will be included in all the *path ope
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="8-10 14-20"
{!../../../docs_src/bigger_applications/app/main.py!}
```

View File

@@ -6,7 +6,7 @@ The same way you can declare additional validation and metadata in *path operati
First, you have to import it:
```Python hl_lines="2"
```Python hl_lines="4"
{!../../../docs_src/body_fields/tutorial001.py!}
```
@@ -17,7 +17,7 @@ First, you have to import it:
You can then use `Field` with model attributes:
```Python hl_lines="9 10"
```Python hl_lines="11-14"
{!../../../docs_src/body_fields/tutorial001.py!}
```
@@ -39,7 +39,7 @@ You can then use `Field` with model attributes:
You can declare extra information in `Field`, `Query`, `Body`, etc. And it will be included in the generated JSON Schema.
You will learn more about it later to declare examples examples.
You will learn more about adding extra information later in the docs, when learning to declare examples.
## Recap

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