Compare commits

...

1234 Commits

Author SHA1 Message Date
Sebastián Ramírez
2b54432a9c 🔖 Release version 0.75.2 2022-04-17 23:08:37 +02:00
Sebastián Ramírez
acd2287b57 📝 Update release notes 2022-04-17 23:07:27 +02:00
github-actions
1d106bd959 📝 Update release notes 2022-04-17 21:01:21 +00:00
Sebastián Ramírez
77fc14eb69 🔧 Update sponsors, add: ExoFlare, Ines Course; remove: Dropbase, Vim.so, Calmcode; update: Striveworks, TalkPython and TestDriven.io (#4805) 2022-04-17 23:00:49 +02:00
github-actions
41d75b6d1c 📝 Update release notes 2022-04-17 20:56:09 +00:00
Sebastián Ramírez
ddd9da3db4 Fix new/recent tests with new fixed ValidationError JSON Schema (#4806) 2022-04-17 20:55:36 +00:00
Sebastián Ramírez
197c1d6dd7 📝 Update release notes 2022-04-17 21:02:49 +02:00
github-actions
d9e7a541fd 📝 Update release notes 2022-04-17 17:42:18 +00:00
dconathan
c449ae5c74 🐛 Fix JSON Schema for ValidationError at field loc (#3810)
Co-authored-by: Devin Conathan <dconatha@amfam.com>
2022-04-17 19:41:46 +02:00
github-actions
1d8d81a6d5 📝 Update release notes 2022-04-17 17:22:26 +00:00
Marcelo Trylesinski
d81c908132 🐛 Fix support for prefix on APIRouter WebSockets (#2640)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2022-04-17 19:21:53 +02:00
github-actions
cb4da93643 📝 Update release notes 2022-04-17 16:18:35 +00:00
Sebastián Ramírez
3cbfae16cf ⬆️ Update ujson ranges for CVE-2021-45958 (#4804) 2022-04-17 16:17:59 +00:00
github-actions
0def8382b8 📝 Update release notes 2022-04-17 15:52:12 +00:00
Sebastián Ramírez
02fae6a38e ⬆️ Upgrade dependencies upper range for extras "all" (#4803) 2022-04-17 15:51:42 +00:00
Sebastián Ramírez
75af472029 📝 Update release notes 2022-04-17 16:55:37 +02:00
github-actions
e1135eddb5 📝 Update release notes 2022-04-17 14:47:55 +00:00
Alan Wright
acf8a91c25 ⬆ Upgrade Swagger UI - swagger-ui-dist@4 (#4347)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2022-04-17 14:47:14 +00:00
github-actions
c4f361c0c4 📝 Update release notes 2022-04-16 08:18:43 +00:00
Sebastián Ramírez
cc57bfcf60 ⬆️ Upgrade Codecov GitHub Action (#4801) 2022-04-16 08:18:08 +00:00
Sebastián Ramírez
26f725d259 🔖 Release version 0.75.1 2022-04-01 18:05:52 -05:00
Sebastián Ramírez
9e018c322c 📝 Update release notes 2022-04-01 18:05:06 -05:00
github-actions
3fefc83d42 📝 Update release notes 2022-04-01 23:02:53 +00:00
github-actions
2c31667407 📝 Update release notes 2022-04-01 23:02:28 +00:00
github-actions[bot]
233214795a 👥 Update FastAPI People (#4752)
Co-authored-by: github-actions <github-actions@github.com>
2022-04-01 18:02:17 -05:00
Sebastián Ramírez
e1d0e3874b Temporarily remove typer-cli from dependencies and upgrade Black (#4754) 2022-04-01 23:01:51 +00:00
github-actions
eddbae948f 📝 Update release notes 2022-03-18 16:48:49 +00:00
Sebastián Ramírez
5c842586c2 🌐 Start Dutch translations (#4703) 2022-03-18 16:47:54 +00:00
github-actions
fc96370ce3 📝 Update release notes 2022-03-18 16:37:49 +00:00
Sebastián Ramírez
d820267cde 🔧 Add configuration to notify Dutch translations (#4702) 2022-03-18 16:37:14 +00:00
github-actions
bd94d313c9 📝 Update release notes 2022-03-18 16:24:54 +00:00
Amin Alaee
2b6f1585ec 🌐 Start Persian/Farsi translations (#4243)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2022-03-18 16:24:19 +00:00
github-actions
bab5c201da 📝 Update release notes 2022-03-17 20:25:09 +00:00
Sarmast Bilawal Khuhro
aec2d26bac ✏ Reword sentence about handling errors (#1993)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2022-03-17 20:24:34 +00:00
github-actions
d5d6eebd40 📝 Update release notes 2022-03-17 20:20:21 +00:00
github-actions[bot]
7982aa5143 👥 Update FastAPI People (#4699)
Co-authored-by: github-actions <github-actions@github.com>
2022-03-17 15:19:43 -05:00
github-actions
fd6ce67392 📝 Update release notes 2022-03-17 18:36:57 +00:00
Sebastián Ramírez
d3eb787090 🐛 Fix FastAPI People generation to include missing file in commit (#4695) 2022-03-17 18:36:21 +00:00
github-actions
6125dc72cd 📝 Update release notes 2022-03-15 15:48:22 +00:00
Sebastián Ramírez
cf8b40e660 🔧 Update Classiq sponsor links (#4688) 2022-03-15 15:47:36 +00:00
github-actions
fab2a765de 📝 Update release notes 2022-03-10 02:30:13 +00:00
Sebastián Ramírez
9aa698aa67 🔧 Add Classiq sponsor (#4671) 2022-03-09 21:29:40 -05:00
Sebastián Ramírez
87e29ec2c5 📝 Update release notes 2022-03-05 19:52:18 +01:00
github-actions
abd148f63a 📝 Update release notes 2022-03-05 18:49:46 +00:00
Sebastián Ramírez
9f38a05954 📝 Add Jina's QA Bot to the docs to help people that want to ask quick questions (#4655)
Co-authored-by: yanlong.wang <yanlong.wang@naiver.org>
2022-03-05 19:49:15 +01:00
Sebastián Ramírez
c89dc736bd 📝 Update release notes 2022-03-04 23:11:21 +01:00
Sebastián Ramírez
19769d0483 🔖 Release version 0.75.0 2022-03-04 23:09:11 +01:00
Sebastián Ramírez
586d17bfb5 📝 Update release notes 2022-03-04 23:08:06 +01:00
github-actions
786b5858e5 📝 Update release notes 2022-03-04 22:02:55 +00:00
Sebastián Ramírez
8a0d4c79c1 Add support for custom generate_unique_id_function and docs for generating clients (#4650) 2022-03-04 23:02:18 +01:00
Sebastián Ramírez
440d2d2d1a 🔖 Release version 0.74.1 2022-02-21 16:54:18 +01:00
github-actions
e953059054 📝 Update release notes 2022-02-21 15:52:03 +00:00
Sebastián Ramírez
f5d7df3c6c Include route in scope to allow middleware and other tools to extract its information (#4603) 2022-02-21 16:51:26 +01:00
Sebastián Ramírez
1ce16c2f40 🔖 Release version 0.74.0 2022-02-17 17:08:23 +01:00
Sebastián Ramírez
03d4d4c38e 📝 Update release notes 2022-02-17 17:05:38 +01:00
github-actions
2d2f1dee5d 📝 Update release notes 2022-02-17 14:18:35 +00:00
Sebastián Ramírez
59e36481dc 🔧 Add Striveworks sponsor (#4596) 2022-02-17 14:18:01 +00:00
github-actions
4fcb00328c 📝 Update release notes 2022-02-17 12:40:46 +00:00
Sebastián Ramírez
9d56a3cb59 Update internal AsyncExitStack to fix context for dependencies with yield (#4575) 2022-02-17 13:40:12 +01:00
github-actions
78b07cb809 📝 Update release notes 2022-02-13 17:19:09 +00:00
Sebastián Ramírez
6034f80687 💚 Only build docs on push when on master to avoid duplicate runs from PRs (#4564) 2022-02-13 18:18:38 +01:00
github-actions
b93f8a709a 📝 Update release notes 2022-02-01 14:28:16 +00:00
github-actions[bot]
618c99d774 👥 Update FastAPI People (#4502)
Co-authored-by: github-actions <github-actions@github.com>
2022-02-01 15:27:34 +01:00
Sebastián Ramírez
291180bf2d 🔖 Release version 0.73.0 2022-01-23 23:38:51 +01:00
Sebastián Ramírez
cbe8d552c1 📝 Update release notes 2022-01-23 23:37:48 +01:00
github-actions
af18d5c49f 📝 Update release notes 2022-01-23 22:14:28 +00:00
Victor Benichoux
a698908ed6 🐛 Fix bug preventing to use OpenAPI when using tuples (#3874)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2022-01-23 23:13:55 +01:00
github-actions
dba9ea8120 📝 Update release notes 2022-01-23 21:31:08 +00:00
Sebastián Ramírez
f8d4d04015 📝 Tweak and improve docs for Request Files (#4470) 2022-01-23 21:30:35 +00:00
github-actions
5a864d8261 📝 Update release notes 2022-01-23 19:14:47 +00:00
Sebastián Ramírez
1bf55200a9 Add support for declaring UploadFile parameters without explicit File() (#4469) 2022-01-23 19:14:13 +00:00
github-actions
59b1f353b3 📝 Update release notes 2022-01-23 17:43:36 +00:00
Sebastián Ramírez
569afb4378 Add support for tags with Enums (#4468) 2022-01-23 18:43:04 +01:00
Sebastián Ramírez
0f8349fcb7 📝 Update release notes 2022-01-23 18:03:42 +01:00
github-actions
6215fdd39e 📝 Update release notes 2022-01-23 16:34:52 +00:00
Vivek Sunder
94ca8c1e29 🐛 Prefer custom encoder over defaults if specified in jsonable_encoder (#2061)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2022-01-23 17:34:18 +01:00
github-actions
f4963f05bf 📝 Update release notes 2022-01-23 16:32:35 +00:00
Sebastián Ramírez
d4608a00cf 🐛 Prefer custom encoder over defaults if specified in jsonable_encoder (#4467)
Co-authored-by: Vivek Sunder <sviveksunder@gmail.com>
2022-01-23 17:32:04 +01:00
github-actions
699b5ef841 📝 Update release notes 2022-01-23 16:14:28 +00:00
Sebastián Ramírez
3de0fb82bf 🐛 Fix docs dependencies cache, to get the latest Material for MkDocs (#4466) 2022-01-23 17:13:49 +01:00
github-actions
85518bc58b 📝 Update release notes 2022-01-23 15:55:36 +00:00
Mark
ca5d57ea79 Allow hiding from OpenAPI (and Swagger UI) Query, Cookie, Header, and Path parameters (#3144)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2022-01-23 16:54:59 +01:00
github-actions
347e391271 📝 Update release notes 2022-01-23 14:56:44 +00:00
Sebastián Ramírez
a75d080124 🔧 Add sponsor Dropbase (#4465) 2022-01-23 15:56:14 +01:00
Sebastián Ramírez
f0388915a8 🔖 Release version 0.72.0 2022-01-16 21:09:10 +01:00
Sebastián Ramírez
9e2f5c67b6 📝 Update release notes 2022-01-16 21:08:04 +01:00
github-actions
93e4a19e35 📝 Update release notes 2022-01-16 19:42:33 +00:00
jaystone776
e1c6d7d310 🌐 Update Chinese translation for docs/help-fastapi.md (#3847) 2022-01-16 20:41:59 +01:00
github-actions
d23b295b96 📝 Update release notes 2022-01-16 19:41:49 +00:00
kty4119
26e94116c1 🌐 Fix Korean translation for docs/ko/docs/index.md (#4195)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2022-01-16 19:41:13 +00:00
github-actions
24968937e5 📝 Update release notes 2022-01-16 19:37:21 +00:00
MicroPanda123
5c5b889288 🌐 Add Polish translation for docs/pl/docs/index.md (#4245)
Co-authored-by: Dawid Dutkiewicz <dutkiewicz@users.noreply.github.com>
Co-authored-by: Dima Tisnek <dimaqq@gmail.com>
Co-authored-by: Bart Skowron <bxsx@bartskowron.com>
Co-authored-by: Bart Skowron <bart.skowron@rollbar.com>
2022-01-16 19:36:42 +00:00
github-actions
436261b3ea 📝 Update release notes 2022-01-16 19:35:00 +00:00
jaystone776
5c62a59e7b 🌐 Add Chinese translation for docs\tutorial\path-operation-configuration.md (#3312)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2022-01-16 19:34:28 +00:00
github-actions
acbe79da37 📝 Update release notes 2022-01-16 19:27:03 +00:00
John Riebold
a85aa125d2 Enable configuring Swagger UI parameters (#2568)
Co-authored-by: Artem Ivanov <artem@worklife.io>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2022-01-16 20:26:24 +01:00
github-actions
9af8cc69d5 📝 Update release notes 2022-01-16 14:44:43 +00:00
Sebastián Ramírez
7fe79441c1 📝 Update Python Types docs, add missing 3.6 / 3.9 example (#4434) 2022-01-16 15:44:08 +01:00
github-actions
b8ae84d460 📝 Update release notes 2022-01-16 14:35:21 +00:00
Sebastián Ramírez
ca2b1dbb64 🔧 Enable MkDocs Material Insiders' content.tabs.link (#4399) 2022-01-16 14:34:45 +00:00
Sebastián Ramírez
672c55ac62 🔖 Release version 0.71.0 2022-01-07 18:07:59 +01:00
github-actions
66c27c3e07 📝 Update release notes 2022-01-07 14:19:23 +00:00
github-actions[bot]
44f4885c66 👥 Update FastAPI People (#4354)
Co-authored-by: github-actions <github-actions@github.com>
2022-01-07 15:18:45 +01:00
github-actions
4da33e3031 📝 Update release notes 2022-01-07 14:17:49 +00:00
Sebastián Ramírez
a1ede32f29 🔧 Add FastAPI Trove Classifier for PyPI (#4386) 2022-01-07 14:17:13 +00:00
github-actions
0a82b3a900 📝 Update release notes 2022-01-07 14:12:16 +00:00
Sebastián Ramírez
d08a062ee2 Add docs and tests for Python 3.9 and Python 3.10 (#3712)
Co-authored-by: Thomas Grainger <tagrain@gmail.com>
2022-01-07 15:11:31 +01:00
github-actions
83f6781037 📝 Update release notes 2022-01-07 10:24:43 +00:00
Sebastián Ramírez
764ecae2d4 ⬆ Upgrade MkDocs Material and configs (#4385) 2022-01-07 11:24:00 +01:00
github-actions
4e9f75912f 📝 Update release notes 2022-01-07 09:35:10 +00:00
simondale00
2b10ca1cc4 ⬆️ Upgrade Starlette to 0.17.1 (#4145)
Co-authored-by: Dima Tisnek <dimaqq@gmail.com>
Co-authored-by: simond <simond@surveymonkey.com>
Co-authored-by: Samuel Colvin <s@muelcolvin.com>
Co-authored-by: Samuel Colvin <samcolvin@gmail.com>
2022-01-07 10:34:28 +01:00
Sebastián Ramírez
3efb4f7edf 🔖 Release version 0.70.1 2021-12-12 12:39:32 +01:00
github-actions
9c25f9615c 📝 Update release notes 2021-12-12 11:34:58 +00:00
github-actions[bot]
e7158bc592 👥 Update FastAPI People (#4274)
Co-authored-by: github-actions <github-actions@github.com>
2021-12-12 12:34:18 +01:00
github-actions
6d642ef5fb 📝 Update release notes 2021-12-12 11:29:36 +00:00
Eric Jolibois
b0cd4d7e7e 🐛 Fix JSON Schema for dataclasses, supporting the fixes in Pydantic 1.9 (#4272)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-12-12 12:28:35 +01:00
github-actions
0a87bc88b8 📝 Update release notes 2021-12-09 10:48:10 +00:00
Nina Hwang
062efcbb5d 🌐 Add Korean translation for docs/tutorial/request-forms-and-files.md (#3744)
Co-authored-by: weekwith.me <63915557+0417taehyun@users.noreply.github.com>
2021-12-09 11:47:26 +01:00
github-actions
aa4a69f790 📝 Update release notes 2021-12-09 10:45:00 +00:00
github-actions
eb79441a7f 📝 Update release notes 2021-12-09 10:40:14 +00:00
Nina Hwang
fa5639cb35 🌐 Add Korean translation for docs/tutorial/request-files.md (#3743)
Co-authored-by: Spike <rurouni24@gmail.com>
Co-authored-by: weekwith.me <63915557+0417taehyun@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-12-08 15:52:01 +00:00
Leandro de Souza
10e3a02582 🌐 Add portuguese translation for docs/tutorial/query-params-str-validations.md (#3965)
Co-authored-by: Mário Victor Ribeiro Silva <mariovictorrs@gmail.com>
Co-authored-by: Leandro de Souza <leandro.souza@fontes.corp>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-12-08 16:50:35 +01:00
github-actions
fb9c4b31b9 📝 Update release notes 2021-12-08 15:46:19 +00:00
Nina Hwang
39dbee9d56 🌐 Add Korean translation for docs/tutorial/response-status-code.md (#3742)
Co-authored-by: weekwith.me <63915557+0417taehyun@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-12-08 16:45:37 +01:00
github-actions
dd463d0dc2 📝 Update release notes 2021-12-08 15:44:10 +00:00
Kwang Soo Jeong
461e0d4cce 🌐 Add Korean translation for Tutorial - JSON Compatible Encoder (#3152) 2021-12-08 16:43:31 +01:00
github-actions
da69a1c4c0 📝 Update release notes 2021-12-08 15:42:12 +00:00
Spike
a5d697b9b5 🌐 Add Korean translation for Tutorial - Path Parameters and Numeric Validations (#2432) 2021-12-08 16:41:26 +01:00
github-actions
8e416875ce 📝 Update release notes 2021-12-08 15:38:10 +00:00
daehyeon kim
446d194c46 🌐 Add Korean translation for docs/ko/docs/deployment/versions.md (#4121)
Co-authored-by: weekwith.me <63915557+0417taehyun@users.noreply.github.com>
2021-12-08 16:37:30 +01:00
github-actions
cace5a79f7 📝 Update release notes 2021-12-08 15:33:09 +00:00
kimjaeyoonn
dabb4898f1 🌐 Fix Korean translation for docs/ko/docs/tutorial/index.md (#4193) 2021-12-08 15:32:24 +00:00
github-actions
f282c0e207 📝 Update release notes 2021-12-08 15:04:50 +00:00
Sebastián Ramírez
146ff28d9c 🔧 Add CryptAPI sponsor (#4264) 2021-12-08 15:04:04 +00:00
github-actions
58ab733f19 📝 Update release notes 2021-10-26 18:54:22 +00:00
weekwith.me
0a61a6c865 📝 Update docs/tutorial/dependencies/classes-as-dependencies: Add type of query parameters in a description of Classes as dependencies (#4015) 2021-10-26 18:53:40 +00:00
github-actions
fb1f341231 📝 Update release notes 2021-10-26 18:47:42 +00:00
Sam Courtemanche
652cf4bb6b 🌐 Add French translation for Tutorial - First steps (#3455)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-26 18:47:01 +00:00
github-actions
08410ca568 📝 Update release notes 2021-10-26 18:34:11 +00:00
Sam Courtemanche
0d5e0ba5d5 🌐 Add French translation for docs/tutorial/path-params.md (#3548)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-26 18:33:34 +00:00
github-actions
b2c9574fc6 📝 Update release notes 2021-10-26 18:16:12 +00:00
Sam Courtemanche
a859497a72 🌐 Add French translation for docs/tutorial/query-params.md (#3556)
Co-authored-by: Ruidy <ruidy.nemausat@gmail.com>
2021-10-26 20:15:30 +02:00
github-actions
3c93e803d5 📝 Update release notes 2021-10-26 18:14:17 +00:00
bilal alpaslan
0bd8f901df 🌐 Add Turkish translation for docs/python-types.md (#3926) 2021-10-26 20:13:34 +02:00
Sebastián Ramírez
864643ef76 📝 Update release notes 2021-10-07 19:38:36 +02:00
Sebastián Ramírez
5d80e02ae8 🔖 Release version 0.70.0 2021-10-07 19:34:27 +02:00
Sebastián Ramírez
affe542753 📝 Update release notes 2021-10-07 19:33:35 +02:00
github-actions
8e887d7145 📝 Update release notes 2021-10-07 17:21:11 +00:00
Sebastián Ramírez
46cf92c55a ⬆️ Upgrade Starlette to 0.16.0 (#4016) 2021-10-07 19:20:30 +02:00
Sebastián Ramírez
921b6f742a 🔖 Release version 0.69.0 2021-10-07 18:45:43 +02:00
Sebastián Ramírez
c1fee263e1 📝 Update release notes 2021-10-07 18:43:50 +02:00
github-actions
42d10ef4bf 📝 Update release notes 2021-10-07 16:22:27 +00:00
Thomas Grainger
637cf89dbd 🔧 Correct DeprecationWarning config and comment in pytest settings (#4008)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-07 18:21:46 +02:00
github-actions
a81e2f20a5 📝 Update release notes 2021-10-07 16:15:21 +00:00
Andy Challis
53076170c0 ✏ Fix typos in Deployment Guide (#3975)
Co-authored-by: Anthony Lukach <anthonylukach@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-07 18:14:39 +02:00
github-actions
eb89968b36 📝 Update release notes 2021-10-07 15:58:17 +00:00
tomwei7
c54fb7e208 📝 Update docs with pip install calls when using extras with brackets, use quotes for compatibility with Zsh (#3131)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-07 17:57:38 +02:00
github-actions
077e5baf2c 📝 Update release notes 2021-10-07 15:56:18 +00:00
Kaustubh Gupta
9c6e0d02bb 📝 Add external link to article: Deploying ML Models as API Using FastAPI and Heroku (#3904)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-07 17:55:40 +02:00
github-actions
d198f38b45 📝 Update release notes 2021-10-07 15:45:28 +00:00
Nina Hwang
4ba1e81f16 ✏ Fix typo in file paths in docs/en/docs/contributing.md (#3752)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-07 17:44:46 +02:00
Jorge Alvarado
b1508dcacc ✏ Re-word and combine 2 paragraphs into 1 for readability (#3346) 2021-10-07 17:39:19 +02:00
github-actions
bb20f5e60d 📝 Update release notes 2021-10-07 15:30:34 +00:00
SaintMalik
7e4887ea55 ✏ Fix a typo in docs/en/docs/advanced/path-operation-advanced-configuration.md and docs/en/docs/release-notes.md (#3750)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-07 15:29:50 +00:00
github-actions
ffaecddbf6 📝 Update release notes 2021-10-07 14:37:59 +00:00
Jorge Alvarado
e43f434448 ✏️ Add a missing comma in the security tutorial (#3564)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-07 14:36:43 +00:00
github-actions
eb453a50b8 📝 Update release notes 2021-10-07 14:23:26 +00:00
jaystone776
5a28f95a93 ✏ Fix typo in docs/en/docs/help-fastapi.md (#3760)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-07 14:22:16 +00:00
github-actions
4093c35058 📝 Update release notes 2021-10-07 14:09:05 +00:00
Denys Marichev
7efdc11075 ✏ Fix typo about file path in docs/en/docs/tutorial/bigger-applications.md (#3285)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-07 14:07:46 +00:00
github-actions
24cda290e8 📝 Update release notes 2021-10-07 13:59:14 +00:00
Bharat Raghunathan
d06b4d7bb8 ✏ Re-word to clarify test client in docs/en/docs/tutorial/testing.md (#3382)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-07 13:57:51 +00:00
github-actions
1a8284725a 📝 Update release notes 2021-10-07 13:32:54 +00:00
Pax
4f168c5ada 📝 Fix incorrect highlighted code (#3325)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-07 13:32:14 +00:00
github-actions
b67532ee5c 📝 Update release notes 2021-10-07 13:27:16 +00:00
Edd Salkield
c29aa0bc87 🔧 Swap light/dark theme button icon (#3246)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-07 15:26:36 +02:00
github-actions
5551e7282c 📝 Update release notes 2021-10-07 13:14:08 +00:00
Somraj Saha
8e68ddbddf 📝 Add external link to article: How-to deploy FastAPI app to Heroku (#3241)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-07 13:13:10 +00:00
github-actions
46882b9ae1 📝 Update release notes 2021-10-07 13:07:24 +00:00
mori yuta
e423c8241a ✏ Fix link in Japanese docs for docs/ja/docs/deployment/docker.md (#3245)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-07 15:06:17 +02:00
github-actions
3581034eff 📝 Update release notes 2021-10-07 13:01:11 +00:00
Abraham Hinteregger
b69781b161 ✏ Fix typo (mistranslation) in docs/en/docs/advanced/templates.md (#3211)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-07 13:00:33 +00:00
github-actions
12db3926b5 📝 Update release notes 2021-10-07 12:57:15 +00:00
Greg Gandenberger
afe1f69e79 📝 Remove note about (now supported) feature from Swagger UI in docs/en/docs/tutorial/request-files.md (#2803)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-07 12:55:51 +00:00
raphaelauv
426bd096ad 📝 Update note about Falcon and ASGI, as now Falcon is also ASGI 🎉 (#3073)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-07 12:44:39 +00:00
Vijay Yarramsetty
0ceacef413 ✏ Fix typo in docs/en/docs/tutorial/body-nested-models.md (#2808)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-07 12:30:25 +00:00
github-actions
fee3126d3a 📝 Update release notes 2021-10-07 12:27:41 +00:00
Hasan Ramezani
8f4e3a4377 📝 Add supported Python versions badge (#2794)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-07 12:26:57 +00:00
github-actions
3b686c3774 📝 Update release notes 2021-10-07 12:22:16 +00:00
graue70
17f0ec8927 ✏ Fix typo re-word in docs/tutorial/handling-errors.md (#2700)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-07 12:21:34 +00:00
github-actions
a6ef62ce7b 📝 Update release notes 2021-10-07 10:36:53 +00:00
Sebastián Ramírez
d9fa2311b3 📝 Add docs for using Trio with Hypercorn (#4014) 2021-10-07 10:36:09 +00:00
github-actions
c15f042318 📝 Update release notes 2021-10-06 15:43:37 +00:00
Sebastián Ramírez
a8bde38f7c Remove graphene as an optional dependency (#4007) 2021-10-06 15:42:55 +00:00
github-actions
496ccc0f70 📝 Update release notes 2021-10-06 15:32:53 +00:00
Thomas Grainger
11d0a08acd Add support for Trio via AnyIO (#3372)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-06 17:32:11 +02:00
github-actions
4d26fa5c54 📝 Update release notes 2021-10-06 15:09:36 +00:00
Sebastián Ramírez
eb1d68c789 🔧 Lint only in Python 3.7 and above (#4006) 2021-10-06 15:08:57 +00:00
github-actions
292b8c8ce9 📝 Update release notes 2021-10-05 16:10:28 +00:00
Sebastián Ramírez
cce8d9e32c 🔧 Add GitHub Action notify-translations config for Azerbaijani (#3995) 2021-10-05 16:09:45 +00:00
github-actions
ac0f594305 📝 Update release notes 2021-10-05 16:08:13 +00:00
Madat Bay
cc0d0f3899 🌐 Initialize Azerbaijani translations (#3941)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-05 16:07:25 +00:00
github-actions
67d5ba1efd 📝 Update release notes 2021-10-05 15:53:54 +00:00
bilal alpaslan
2210c84efd 🌐 Add Turkish translation for docs/fastapi-people.md (#3848)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-05 15:47:51 +00:00
Sebastián Ramírez
378fa4ef75 🔖 Release version 0.68.2 2021-10-05 15:32:18 +02:00
Sebastián Ramírez
eb515b1af7 📝 Re-structure release notes 2021-10-05 15:31:39 +02:00
github-actions
19fd336cde 📝 Update release notes 2021-10-05 13:02:28 +00:00
Yagiz Degirmenci
63744b2e8a 🌐 Add Turkish translation for docs/features.md (#1950)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-05 15:01:50 +02:00
github-actions
85f0d2b924 📝 Update release notes 2021-10-05 12:51:14 +00:00
Hüseyin Emre Armağan
507e9baf9e 🌐 Add Turkish translation for docs/benchmarks.md (#2729)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-05 12:50:38 +00:00
github-actions
c6461ad7dc 📝 Update release notes 2021-10-05 12:46:49 +00:00
Yagiz Degirmenci
5fbf597cd5 🌐 Add Turkish translation for docs/index.md (#1908)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-05 12:46:11 +00:00
github-actions
bc99d2b7b8 📝 Update release notes 2021-10-05 12:31:22 +00:00
Sam Courtemanche
0eb27ab4d0 🌐 Add French translation for docs/tutorial/body.md (#3671)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-05 12:30:41 +00:00
github-actions
68c43eb126 📝 Update release notes 2021-10-05 12:28:05 +00:00
Ruidy
00ac07f65c 🌐 Add French translation for deployment/docker.md (#3694)
Co-authored-by: Sam Courtemanche <smlep.pro@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-05 14:27:24 +02:00
github-actions
d8b0a9dc6e 📝 Update release notes 2021-10-05 12:19:45 +00:00
Felipe Silva
8c36572d23 🌐 Add Portuguese translation for docs/tutorial/path-params.md (#3664)
Co-authored-by: Mário Victor Ribeiro Silva <mariovictorrs@gmail.com>
Co-authored-by: Izabela Guerreiro <izaguerreiro@gmail.com>
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
Co-authored-by: Lucas <61513630+lsglucas@users.noreply.github.com>
Co-authored-by: Felipe <dasilva.delipex93@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-05 12:19:03 +00:00
jaystone776
e0e3224588 🌐 Delete old Chinese translation for docs/deployment.md (#3840)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-05 11:03:59 +00:00
github-actions
4e2595f928 📝 Update release notes 2021-10-05 10:40:42 +00:00
Lucas
6de8748788 🌐 Add Portuguese translation for docs/deployment/https.md (#3754) 2021-10-05 12:40:05 +02:00
github-actions
39ec5b33d9 📝 Update release notes 2021-10-05 10:24:47 +00:00
Sebastián Ramírez
557fe61d92 Update GitHub Action: notify-translations, to avoid a race conditon (#3989) 2021-10-05 10:24:02 +00:00
github-actions
458a7fbf15 📝 Update release notes 2021-10-05 10:18:13 +00:00
Sebastián Ramírez
ae22bca9fe ⬆️ Upgrade development autoflake, supporting multi-line imports (#3988) 2021-10-05 10:17:31 +00:00
github-actions
9229ba8078 📝 Update release notes 2021-10-05 10:08:26 +00:00
Sebastián Ramírez
96ca425b1f ⬆️ Increase dependency ranges for tests and docs: pytest-cov, pytest-asyncio, black, httpx, sqlalchemy, databases, mkdocs-markdownextradata-plugin (#3987) 2021-10-05 10:07:40 +00:00
github-actions
c86a4e1dd3 📝 Update release notes 2021-10-05 09:55:12 +00:00
github-actions[bot]
24749aef71 👥 Update FastAPI People (#3986)
Co-authored-by: github-actions <github-actions@github.com>
2021-10-05 11:54:36 +02:00
github-actions
f6a3bc2902 📝 Update release notes 2021-10-05 09:17:56 +00:00
SnkSynthesis
ba8c78d87f ⬆Increase supported version of aiofiles to suppress warnings (#2899)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-05 11:17:14 +02:00
github-actions
69784e5141 📝 Update release notes 2021-10-05 08:58:41 +00:00
Filipe Laíns
8a02a47124 Do not require backports in Python >= 3.7 (#1880)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-05 10:58:00 +02:00
github-actions
5607c198c4 📝 Update release notes 2021-10-05 08:47:25 +00:00
Taneli Hukkinen
cf5e67590a ⬆ Upgrade required Python version to >= 3.6.1, needed by typing.Deque, used by Pydantic (#2733)
Co-authored-by: Taneli Hukkinen <hukkinj1@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-05 10:46:42 +02:00
github-actions
655db2af1f 📝 Update release notes 2021-10-05 08:40:44 +00:00
ArcLight_Slavik
8c102814fd ⬆ Upgrade internal testing dependencies: mypy to version 0.910, add newly needed type packages (#3350)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-05 10:40:08 +02:00
github-actions
189ac3e280 📝 Update release notes 2021-10-05 08:07:20 +00:00
Marcelo Trylesinski
2680f369d0 ⬆️ Bump Uvicorn max range to 0.15.0 (#3345)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-05 10:06:35 +02:00
github-actions
284eb6615d 📝 Update release notes 2021-10-03 18:14:25 +00:00
Andy Challis
099c478655 💚 Fix badges in README and main page (#3979)
Co-authored-by: Anthony Lukach <anthonylukach@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-10-03 20:13:47 +02:00
github-actions
54c02d402a 📝 Update release notes 2021-10-03 18:01:11 +00:00
Sebastián Ramírez
4b968c4e39 📝 Update GraphQL docs, recommend Strawberry (#3981) 2021-10-03 20:00:28 +02:00
github-actions
1db0fc2953 📝 Update release notes 2021-10-02 10:17:32 +00:00
Sebastián Ramírez
d29aa3d436 Add Deepset Sponsorship (#3976) 2021-10-02 12:16:55 +02:00
github-actions
1b6350ad9e 📝 Update release notes 2021-10-01 20:44:53 +00:00
Sebastián Ramírez
cb7e79ab8a 📝 Re-write and extend Deployment guide: Concepts, Uvicorn, Gunicorn, Docker, Containers, Kubernetes (#3974) 2021-10-01 22:44:19 +02:00
github-actions
fe086a4903 📝 Update release notes 2021-09-27 14:41:20 +00:00
Sebastián Ramírez
64e7deaebc 📝 Upgrade HTTPS guide with more explanations and diagrams (#3950) 2021-09-27 14:40:38 +00:00
github-actions
bee35f5ae1 📝 Update release notes 2021-09-13 17:29:47 +00:00
Maximilian Wassink
3a786a7a3a 🌐 Add German translation for docs/features.md (#3699) 2021-09-13 19:29:03 +02:00
github-actions
eaeafc32c4 📝 Update release notes 2021-09-10 14:29:04 +00:00
Sebastián Ramírez
c8b4e4d455 🎨 Tweak CSS styles for shell animations (#3888) 2021-09-10 14:28:22 +00:00
github-actions
1760da0efa 📝 Update release notes 2021-08-27 08:49:40 +00:00
Sebastián Ramírez
f49ba24b71 🔧 Add new Sponsor Calmcode.io (#3777) 2021-08-27 08:49:08 +00:00
Sebastián Ramírez
7b6e198d31 🔖 Release version 0.68.1 2021-08-24 14:16:09 +02:00
Sebastián Ramírez
6ac35b1c2a 📝 Update release notes 2021-08-24 14:13:47 +02:00
github-actions
dc9c570733 📝 Update release notes 2021-08-24 10:21:45 +00:00
Sebastián Ramírez
20d4834546 Add support for read_with_orm_mode, to support SQLModel relationship attributes (#3757) 2021-08-24 10:21:05 +00:00
github-actions
f7d7c6c865 📝 Update release notes 2021-08-19 08:21:59 +00:00
Mário Victor Ribeiro Silva
c03b9b2d4c 🌐 Add Portuguese translation of docs/fastapi-people.md (#3461)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-08-19 10:21:21 +02:00
github-actions
70f1b8ebd0 📝 Update release notes 2021-08-18 13:50:17 +00:00
jaystone776
13bf477579 🌐 Add Chinese translation for docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md (#3492)
Co-authored-by: Waynerv <ampedee@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-08-18 13:49:44 +00:00
github-actions
ab5afd0b42 📝 Update release notes 2021-08-18 13:44:46 +00:00
Sebastián Ramírez
b5dcd98605 🔧 Add new Translation tracking issues for German and Indonesian (#3718) 2021-08-18 13:44:11 +00:00
github-actions
2280a48c67 📝 Update release notes 2021-08-18 13:32:37 +00:00
jaystone776
8c5d1f30dc 🌐 Add Chinese translation for docs/tutorial/dependencies/sub-dependencies.md (#3491)
Co-authored-by: Waynerv <ampedee@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-08-18 13:31:59 +00:00
github-actions
98a0fe8628 📝 Update release notes 2021-08-18 13:27:46 +00:00
Mário Victor Ribeiro Silva
38c52fa12d 🌐 Add Portuguese translation for docs/advanced/index.md (#3460)
Co-authored-by: Lucas <61513630+lsglucas@users.noreply.github.com>
2021-08-18 15:27:05 +02:00
github-actions
7c2ed25d6f 📝 Update release notes 2021-08-18 13:24:58 +00:00
Fabio Serrao
dda105c50d 🌐 Portuguese translation of docs/async.md (#1330)
Co-authored-by: Lucas <61513630+lsglucas@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-08-18 13:24:21 +00:00
github-actions
326837443f 📝 Update release notes 2021-08-18 13:20:25 +00:00
Sam Courtemanche
cb5b4e1b7e 🌐 Add French translation for docs/async.md (#3416)
Co-authored-by: Jacquet Corentin <corentin.jacquet@telecomnancy.net>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-08-18 15:19:43 +02:00
github-actions
a23eaaeda8 📝 Update release notes 2021-08-18 13:07:50 +00:00
Sebastián Ramírez
d0ced2c7c9 Add GitHub Action: Notify Translations (#3715) 2021-08-18 15:07:08 +02:00
github-actions
3409c9e32f 📝 Update release notes 2021-08-18 09:48:18 +00:00
Sebastián Ramírez
53a86a885d Update computation of FastAPI People and sponsors (#3714) 2021-08-18 09:47:39 +00:00
github-actions
4ac310875d 📝 Update release notes 2021-08-17 20:47:40 +00:00
Sebastián Ramírez
30e742d566 Enable recent Material for MkDocs Insiders features (#3710) 2021-08-17 20:47:05 +00:00
github-actions
84490a2160 📝 Update release notes 2021-08-17 20:01:09 +00:00
Sebastián Ramírez
4d4452ede5 🔥 Remove/clean extra imports from examples in docs for features (#3709) 2021-08-17 20:00:29 +00:00
github-actions
25a48287ed 📝 Update release notes 2021-08-02 14:54:26 +00:00
Sebastián Ramírez
9a33a0e24c Update docs library to include sources in Markdown (#3648) 2021-08-02 14:53:52 +00:00
github-actions
27fd954a45 📝 Update release notes 2021-08-02 14:03:15 +00:00
Marcelo Trylesinski
ab33ba27af ⬆ Add support for Python 3.9 (#2298)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-08-02 16:02:34 +02:00
github-actions
e9ba01dc59 📝 Update release notes 2021-08-02 13:42:35 +00:00
github-actions[bot]
e809bdc170 👥 Update FastAPI People (#3642)
Co-authored-by: github-actions <github-actions@github.com>
2021-08-02 15:42:02 +02:00
Sebastián Ramírez
717a1ec409 🔖 Release version 0.68.0 2021-07-29 23:03:57 +02:00
Sebastián Ramírez
eba2c66532 🔖 Update release notes 2021-07-29 23:02:42 +02:00
github-actions
3788ca4640 📝 Update release notes 2021-07-29 21:00:53 +00:00
Sebastián Ramírez
97fa743ecb Update OpenAPI models, supporting recursive models and extensions (#3628) 2021-07-29 20:59:26 +00:00
github-actions
e726b7b771 📝 Update release notes 2021-07-29 20:28:25 +00:00
github-actions
6a22b75afd 📝 Update release notes 2021-07-29 20:25:17 +00:00
github-actions
4093d9b22a 📝 Update release notes 2021-07-29 20:23:19 +00:00
Urchin
18daf8f301 🌐 Add Russian translation for docs/python-types.md (#3039) 2021-07-29 22:22:43 +02:00
jaystone776
962578bec2 🌐 Add Chinese translation for docs/tutorial/dependencies/index.md (#3489)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-29 22:21:38 +02:00
Urchin
85cff59109 🌐 Add Russian translation for docs/external-links.md (#3036) 2021-07-29 20:21:06 +00:00
github-actions
b869c7c872 📝 Update release notes 2021-07-29 20:16:29 +00:00
jaystone776
016c3f0d5b 🌐 Add Chinese translation for docs/tutorial/dependencies/global-dependencies.md (#3493)
as title
2021-07-29 22:15:54 +02:00
github-actions
4eb9c60652 📝 Update release notes 2021-07-29 20:15:22 +00:00
Lucas
8879757a88 🌐 Add Portuguese translation for docs/deployment/versions.md (#3618)
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
2021-07-29 22:14:40 +02:00
Sebastián Ramírez
fadfcfda4a 📝 Update release notes 2021-07-29 22:12:55 +02:00
github-actions
b8c4149e89 📝 Update release notes 2021-07-29 20:01:49 +00:00
Edouard Lavery-Plante
836bb97a2d Add support for extensions and updates to the OpenAPI schema in path operations (#1922)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-29 22:01:13 +02:00
github-actions
7db359182d 📝 Update release notes 2021-07-29 15:30:57 +00:00
James Curtin
4eada92883 Import and re-export data structures from Starlette, used by Request properties, on fastapi.datastructures (#1872)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-29 17:30:18 +02:00
github-actions
6a74f3a0c1 📝 Update release notes 2021-07-29 15:18:55 +00:00
Edward Knight
daa0765653 📝 Update docs about async and response-model with more gender neutral language (#1869) 2021-07-29 17:18:20 +02:00
github-actions
27e26b5939 📝 Update release notes 2021-07-29 15:10:59 +00:00
dkreeft
6f45f43709 Add additonal OpenAPI metadata parameters to FastAPI class, shown on the automatic API docs UI (#1812)
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
Co-authored-by: dkreeft <dkreeft@xccelerated.io>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-29 17:10:22 +02:00
github-actions
6c80e9a8e0 📝 Update release notes 2021-07-29 10:31:22 +00:00
Hylke Postma
3b2e891917 Add description parameter to all the security scheme classes, e.g. APIKeyQuery(name="key", description="A very cool API key") (#1757)
Co-authored-by: Hylke Postma <h.postma@docuwork.nl>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-29 12:30:48 +02:00
github-actions
9121fccf55 📝 Update release notes 2021-07-29 09:26:40 +00:00
Marcelo Trylesinski
fa2c750443 Add the docs_src directory to test coverage and update tests (#1904)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-29 11:26:07 +02:00
github-actions
29e7b31ee6 📝 Update release notes 2021-07-28 15:36:03 +00:00
Yuya Sato
bb6c6ed5d1 🌐 Add Japanese translation for docs/tutorial/security/oauth2-jwt.md (#3526)
Co-authored-by: tokusumi <41147016+tokusumi@users.noreply.github.com>
Co-authored-by: Sho Nakamura <sh0nk.developer@gmail.com>
2021-07-28 17:35:25 +02:00
github-actions
1a5273773e 📝 Update release notes 2021-07-27 10:23:49 +00:00
Sebastián Ramírez
3f40c37905 🔧 Add new GitHub templates with forms for new issues (#3612) 2021-07-27 10:23:09 +00:00
Sebastián Ramírez
996dfd05bd 📝 Update release notes 2021-07-21 21:15:58 +02:00
github-actions
0a1dd7894c 📝 Update release notes 2021-07-21 19:14:32 +00:00
Sebastián Ramírez
dbfd3f7e18 📝 Add official FastAPI Twitter to docs (#3578) 2021-07-21 21:13:58 +02:00
Sebastián Ramírez
a0209a0d2c 🔖 Release version 0.67.0 2021-07-21 20:00:39 +02:00
Sebastián Ramírez
099aab79e6 📝 Update release notes 2021-07-21 19:59:38 +02:00
github-actions
7dc5b94d45 📝 Update release notes 2021-07-21 17:54:42 +00:00
Sebastián Ramírez
684c0077cc Add support for dataclasses in request bodies and response_model (#3577) 2021-07-21 19:54:08 +02:00
github-actions
75d8a6b5c2 📝 Update release notes 2021-07-21 14:39:54 +00:00
Sebastián Ramírez
96fdfc53cc Support dataclasses in responses (#3576)
Co-authored-by: amit lissack <amit@opentrons.com>
2021-07-21 14:39:12 +00:00
github-actions
49517d3310 📝 Update release notes 2021-07-21 13:16:08 +00:00
Ehigie Aito
9355cc4eaa 📝 Add external link: How to Create A Fake Certificate Authority And Generate TLS Certs for FastAPI (#2839)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-21 13:15:33 +00:00
github-actions
1ce59152e7 📝 Update release notes 2021-07-21 12:44:53 +00:00
jaystone776
1241f7f0b7 ✏ Fix code highlighted line in: body-nested-models.md (#3463) 2021-07-21 14:44:15 +02:00
github-actions
fd74c0f6a4 📝 Update release notes 2021-07-21 12:42:05 +00:00
jaystone776
e4eac12c34 ✏ Fix typo in body-nested-models.md (#3462)
Typo in line 201, *where* should be *were*
2021-07-21 14:41:24 +02:00
github-actions
b235653a6c 📝 Update release notes 2021-07-21 12:37:40 +00:00
David Brakman
4cb4bdb984 ✏ Fix typo "might me" -> "might be" in docs/en/docs/tutorial/schema-extra-example.md (#3362)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-21 12:37:06 +00:00
github-actions
ba596152d9 📝 Update release notes 2021-07-21 12:28:48 +00:00
Shahriyar Rzayev
a1227624c8 📝 Add external link: Building simple E-Commerce with NuxtJS and FastAPI (#3271)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-21 12:28:15 +00:00
github-actions
9ce1ae771c 📝 Update release notes 2021-07-21 12:21:46 +00:00
Rodrigo Arenas
b9fed9b485 📝 Add external link: Serve a machine learning model using Sklearn, FastAPI and Docker (#2974)
Co-authored-by: rodrigoarenas456 <31422766+rodrigoarenas456@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-21 14:20:53 +02:00
github-actions
0d97e1f97d 📝 Update release notes 2021-07-21 12:15:08 +00:00
Marcelo Trylesinski
1ce7258a01 ✏️ Fix typo on docstring in datastructures file (#2887) 2021-07-21 14:14:34 +02:00
github-actions
bcd06fdfdf 📝 Update release notes 2021-07-21 12:11:22 +00:00
Marcelo Trylesinski
fc35b7d18d 🎨 Improve style for sponsors, add radius border (#2388)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-21 14:10:47 +02:00
github-actions
8c12ab0d5b 📝 Update release notes 2021-07-21 11:15:03 +00:00
Sebastián Ramírez
38194a29bc 📝 Add External Link: Deploy FastAPI on Ubuntu and Serve using Caddy 2 Web Server (#3572) 2021-07-21 13:14:28 +02:00
github-actions
6b65de6033 📝 Update release notes 2021-07-21 11:12:47 +00:00
github-actions
f80230d654 📝 Update release notes 2021-07-21 11:11:43 +00:00
github-actions
f6cc418d79 📝 Update release notes 2021-07-21 11:10:13 +00:00
github-actions
3ce9407093 📝 Update release notes 2021-07-21 11:08:47 +00:00
github-actions
ef1716c39e 📝 Update release notes 2021-07-21 10:42:13 +00:00
Sebastián Ramírez
9ab7da6562 👷 Update GitHub Action latest-changes, strike 2 (#3575) 2021-07-21 10:41:32 +00:00
Sebastián Ramírez
fcfff5e8e5 👷 Update GitHub Action latest-changes (#3574) 2021-07-21 10:33:42 +00:00
Sebastián Ramírez
67ef62a4dd 👷 Update GitHub Action latest-changes (#3573) 2021-07-21 09:54:27 +00:00
Sebastián Ramírez
7741635b3b 🔧 Add External Link, replaces #1898 (#3571) 2021-07-21 09:39:12 +00:00
Sebastián Ramírez
3d81bc638b 👷 Rename and clarify CI workflow job names (#3570) 2021-07-21 11:24:40 +02:00
github-actions
c1801738b0 📝 Update release notes 2021-07-21 08:52:50 +00:00
Sebastián Ramírez
ba84f167f5 🔧 Sort external links in docs to have the most recent at the top (#3568) 2021-07-21 10:52:10 +02:00
Sebastián Ramírez
0a38c51b9e 🔖 Release 0.66.1 2021-07-19 21:26:52 +02:00
Sebastián Ramírez
db5b2bdf56 📝 Update release notes 2021-07-19 21:21:40 +02:00
github-actions
5ac84120b3 📝 Update release notes 2021-07-19 19:15:35 +00:00
Thomas Grainger
2d296c5d07 🔧 Configure strict pytest options and update/refactor tests (#2790)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-19 21:14:58 +02:00
github-actions
71c96d9eb9 📝 Update release notes 2021-07-19 12:49:41 +00:00
Mark H
5342a0a00f 🌐 Add basic setup for German translations (#3522) 2021-07-19 14:49:09 +02:00
github-actions
163b086f21 📝 Update release notes 2021-07-19 12:47:20 +00:00
oandersonmagalhaes
0876d3df1d 🌐 Add Portuguese translation for docs/tutorial/security/index.md (#3507)
Co-authored-by: Izabela Guerreiro <izaguerreiro@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-19 14:46:39 +02:00
github-actions
50baf5e804 📝 Update release notes 2021-07-19 12:33:34 +00:00
Lucas
3d6da2c32d 🌐 Add Portuguese translation for docs/deployment/index.md (#3337) 2021-07-19 14:32:54 +02:00
github-actions
e721d04350 📝 Update release notes 2021-07-05 11:45:43 +00:00
Sebastián Ramírez
8cc6f9baac ⬆️ Upgrade python-jose dependency for tests (#3468) 2021-07-05 13:45:03 +02:00
Sebastián Ramírez
dfd453e001 📝 Update release notes 2021-07-04 21:18:45 +02:00
Sebastián Ramírez
7e9d5aacf8 🔖 Release version 0.66.0 2021-07-04 20:59:46 +02:00
Sebastián Ramírez
d27a218bc3 📝 Update release notes 2021-07-04 20:58:49 +02:00
github-actions
0c4ded88fe 📝 Update release notes 2021-07-04 18:54:19 +00:00
Rubikoid
0e0931d308 🐛 Fix include/exclude for dicts in jsonable_encoder (#2016)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-04 20:53:40 +02:00
github-actions
dcfa9eb8fe 📝 Update release notes 2021-07-04 17:35:19 +00:00
Camila Gutierrez
6ebf60b175 🌐 Add Spanish translation for tutorial/query-params.md (#2243)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-04 19:34:46 +02:00
github-actions
a4d0724a97 📝 Update release notes 2021-07-04 17:06:51 +00:00
Juan Funez
c235e9b78c 🌐 Add Spanish translation for advanced/response-directly.md (#1253)
Co-authored-by: Camila Gutierrez <mariacamilagl30@gmail.com>
2021-07-04 19:06:18 +02:00
github-actions
5fa3e239db 📝 Update release notes 2021-07-04 14:15:04 +00:00
Juan Funez
3d1b107d70 🌐 Add Spanish translation for advanced/additional-status-codes.md (#1252)
Co-authored-by: Camila Gutierrez <mariacamilagl30@gmail.com>
2021-07-04 16:14:29 +02:00
github-actions
18e0828daf 📝 Update release notes 2021-07-04 12:50:02 +00:00
Juan Funez
f16c7729bd 🌐 Add Spanish translation for advanced/path-operation-advanced-configuration.md (#1251)
Co-authored-by: Camila Gutierrez <mariacamilagl@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
Co-authored-by: Camila Gutierrez <mariacamilagl30@gmail.com>
2021-07-04 14:49:31 +02:00
Sebastián Ramírez
9f3c8cd139 📝 Update release notes, add links to docs 2021-07-03 21:59:39 +02:00
github-actions
a7a35aee61 📝 Update release notes 2021-07-03 19:52:03 +00:00
Sebastián Ramírez
dc5a966548 Allow setting the response_class to RedirectResponse and returning the URL from the function (#3457) 2021-07-03 21:51:28 +02:00
github-actions
ea8d7f689e 📝 Update release notes 2021-07-03 17:16:33 +00:00
Jacob Magnusson
0ed6c92341 🐛 Support custom OpenAPI / JSON Schema fields in the generated output OpenAPI (#1429)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-03 19:15:59 +02:00
Sebastián Ramírez
79f52c76cf 🔖 Release version 0.65.3 2021-07-03 18:33:32 +02:00
Sebastián Ramírez
b725e9eb45 📝 Update release notes 2021-07-03 18:32:50 +02:00
Sebastián Ramírez
787e54b096 📝 Update release notes 2021-07-03 18:30:46 +02:00
github-actions
15fd60b29a 📝 Update release notes 2021-07-03 16:26:48 +00:00
Sebastián Ramírez
edf6b2d61f ♻ Assume request bodies contain JSON when no Content-Type header is provided (#3456) 2021-07-03 18:25:12 +02:00
github-actions
7eb17fc874 📝 Update release notes 2021-07-03 15:13:30 +00:00
Nasaruddin
7e4bfaf0e9 🌐 Initialize Indonesian translations (#3014)
Co-authored-by: Nasaruddin <nasaruddin@skorpoints.com>
2021-07-03 17:12:51 +02:00
github-actions
e1d4fc5325 📝 Update release notes 2021-07-03 14:47:21 +00:00
Camila Gutierrez
faec748ef6 🌐 Add Spanish translation of Tutorial - Path Parameters (#2219)
Co-authored-by: Pedro A. Moreno <pedabraham@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-03 16:46:49 +02:00
github-actions
afec8c4580 📝 Update release notes 2021-07-03 14:14:01 +00:00
Camila Gutierrez
8a1f0aa3b6 🌐 Add Spanish translation of Tutorial - First Steps (#2208)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-03 16:13:28 +02:00
github-actions
f784644510 📝 Update release notes 2021-07-02 15:18:24 +00:00
github-actions[bot]
710a2f745c 👥 Update FastAPI People (#3450)
Co-authored-by: github-actions <github-actions@github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-02 17:17:49 +02:00
github-actions
bd230fe473 📝 Update release notes 2021-07-02 15:00:53 +00:00
Mário Victor Ribeiro Silva
9c5b000956 🌐 Portuguese translation of Tutorial - Body - Fields (#3420)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-02 17:00:11 +02:00
github-actions
a9f2a25feb 📝 Update release notes 2021-07-02 14:54:56 +00:00
jaystone776
c00c2d1ecf 🌐 Add Chinese translation for Tutorial - Request - Forms - and - Files (#3249)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-02 16:54:22 +02:00
github-actions
dd7bbae837 📝 Update release notes 2021-07-02 14:44:04 +00:00
jaystone776
0a84d48a82 🌐 Add Chinese translation for Tutorial - Handling - Errors (#3299)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-02 16:43:28 +02:00
github-actions
e5d0b97dee 📝 Update release notes 2021-07-02 14:36:34 +00:00
jaystone776
811c3f873f 🌐 Add Chinese translation for Tutorial - Form - Data (#3248)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-02 16:35:58 +02:00
github-actions
662fc81544 📝 Update release notes 2021-07-02 14:27:36 +00:00
github-actions[bot]
5e2f2d541d 👥 Update FastAPI People (#3319)
Co-authored-by: github-actions <github-actions@github.com>
2021-07-02 16:27:02 +02:00
github-actions
8116d8158b 📝 Update release notes 2021-07-02 14:24:16 +00:00
jaystone776
e6836781d5 🌐 Add Chinese translation for Tutorial - Body - Updates (#3237)
Co-authored-by: Xie Wei <ampedee@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-02 16:23:41 +02:00
github-actions
098088c763 📝 Update release notes 2021-07-02 14:21:11 +00:00
Hareru
4bf9a52043 🌐 Add Chinese translation for FastAPI People (#3112)
Co-authored-by: Xie Wei <ampedee@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-02 16:20:36 +02:00
github-actions
eb6f964ede 📝 Update release notes 2021-07-02 14:18:44 +00:00
Sam Courtemanche
4473a9bcbf 🌐 Add French translation for Project Generation (#3197)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-02 16:18:06 +02:00
github-actions
fdc7c96ece 📝 Update release notes 2021-07-02 14:14:28 +00:00
Sam Courtemanche
a694be81ae 🌐 Add French translation for Python Types Intro (#3185) 2021-07-02 16:13:52 +02:00
github-actions
0abb743e9c 📝 Update release notes 2021-07-02 14:12:43 +00:00
Sam Courtemanche
acda3f06b0 🌐 Add French translation for External Links (#3103)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-07-02 16:12:05 +02:00
github-actions
3127bc4e05 📝 Update release notes 2021-07-02 14:06:45 +00:00
Ruidy
18b24df9c8 🌐 Add French translation for Alternatives, Inspiration and Comparisons (#3020)
Co-authored-by: Jérôme Fink <jerome.fink@student.unamur.be>
Co-authored-by: Sam Courtemanche <sam.courtemanche.ipod@gmail.com>
2021-07-02 16:06:10 +02:00
github-actions
b27758fe13 📝 Update release notes 2021-07-02 14:03:22 +00:00
BoYanZh
a0b2006230 🌐 Fix Chinese translation code snippet mismatch in Tutorial - Python Types Intro 2021-07-02 16:02:45 +02:00
github-actions
bd143ffa5a 📝 Update release notes 2021-07-02 13:43:04 +00:00
Fabio Serrao
77c1988a8b 🌐 Add Portuguese translation for Development Contributing (#1364) 2021-07-02 15:42:29 +02:00
github-actions
26a36f79fa 📝 Update release notes 2021-06-29 21:23:00 +00:00
Sebastián Ramírez
97d8d4016b ⬆ Upgrade docs development dependency on typer-cli to >=0.0.12 to fix conflicts (#3429) 2021-06-29 23:22:23 +02:00
github-actions
246e80512d 📝 Update release notes 2021-06-29 12:24:59 +00:00
jaystone776
fc6827d68a 🌐 Add Chinese translation for Tutorial - Request - Files (#3244)
Co-authored-by: Xie Wei <ampedee@gmail.com>
2021-06-29 14:24:19 +02:00
Sebastián Ramírez
4d91f978d2 🔖 Release version 0.65.2 2021-06-09 10:17:27 +02:00
Sebastián Ramírez
aabe2c7d66 📝 Update release notes 2021-06-09 10:16:25 +02:00
Sebastián Ramírez
377234ad8e 🔒 Create Security Policy 2021-06-07 14:55:40 +02:00
github-actions
38b785813f 📝 Update release notes 2021-06-07 10:46:59 +00:00
Patrick Wang
fa7e3c996e 🐛 Check Content-Type request header before assuming JSON (#2118)
Co-authored-by: Patrick Wang <patrickkwang@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-06-07 12:46:18 +02:00
github-actions
90120dd6e8 📝 Update release notes 2021-06-07 08:53:24 +00:00
Sebastián Ramírez
36772548b7 🔧 Update sponsors badge, course bundle (#3340)
* 🔧 Update sponsors badge, course bundle

* 🍱 Update course bundle SVG sizes
2021-06-07 10:52:44 +02:00
github-actions
40bb0c5f36 📝 Update release notes 2021-05-26 09:26:47 +00:00
Sebastián Ramírez
60918d25a1 🔧 Add new gold sponsor Jina 🎉 (#3291) 2021-05-26 11:26:06 +02:00
github-actions
3afce2c4b8 📝 Update release notes 2021-05-25 15:06:28 +00:00
Sebastián Ramírez
9f6f25d54c 🔧 Add new banner sponsor badge for FastAPI courses bundle (#3288) 2021-05-25 17:05:39 +02:00
Sebastián Ramírez
d5b09cd958 🔧 Add new banner sponsor badge for FastAPI courses bundle (#3288) 2021-05-25 17:05:04 +02:00
github-actions
aece74982d 📝 Update release notes 2021-05-16 18:28:24 +00:00
Sebastián Ramírez
2b1e5b9f82 👷 Upgrade Issue Manager GitHub Action (#3236) 2021-05-16 20:27:45 +02:00
Sebastián Ramírez
43df5d05ed 🔖 Release FastAPI version 0.65.1 2021-05-11 23:19:14 +02:00
github-actions
eaa49ebd20 📝 Update release notes 2021-05-11 21:17:51 +00:00
Sebastián Ramírez
a6293397bc 📌 Upgrade pydantic pin, to handle security vulnerability CVE-2021-29510 (#3213) 2021-05-11 23:17:17 +02:00
Sebastián Ramírez
b890bd1dc5 🔖 Release version 0.65.0 2021-05-10 17:45:21 +02:00
github-actions
3819a11b5f 📝 Update release notes 2021-05-10 14:09:42 +00:00
Hannes Küttner
4aed0411e9 ⬆️ Upgrade Starlette to 0.14.2, including internal UJSONResponse migrated from Starlette (#2335) 2021-05-10 16:09:04 +02:00
github-actions
04ac466748 📝 Update release notes 2021-05-10 08:11:22 +00:00
Sebastián Ramírez
d75126a4ce 👷 Add GitHub Action cache to speed up CI installs (#3204) 2021-05-10 10:10:48 +02:00
github-actions
c654e8384b 📝 Update release notes 2021-05-10 07:47:11 +00:00
Sebastián Ramírez
7c9d0168ff ⬆️ Upgrade setup-python GitHub Action to v2 (#3203) 2021-05-10 09:46:32 +02:00
github-actions
e956ba4d4a 📝 Update release notes 2021-05-10 07:27:43 +00:00
neternefer
85b32f51ff 🌐 Initialize new language Polish for translations (#3170)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-05-10 09:27:07 +02:00
github-actions
08fabb7b2e 📝 Update release notes 2021-05-10 07:16:15 +00:00
Sebastián Ramírez
273b2cd646 🐛 Fix docs script to generate a new translation language with overrides boilerplate (#3202) 2021-05-10 09:15:39 +02:00
github-actions
de1a5125f8 📝 Update release notes 2021-05-08 17:51:32 +00:00
Sebastián Ramírez
da86791224 Add new Deta banner badge with new sponsorship tier 🙇 (#3194) 2021-05-08 19:50:56 +02:00
Sebastián Ramírez
c646eaa6bb ✏️ Fix typo/order in release notes 2021-05-07 14:25:21 +02:00
github-actions
bf44b428dd 📝 Update release notes 2021-05-07 12:19:57 +00:00
github-actions[bot]
c2907b189c 👥 Update FastAPI People (#3189)
Co-authored-by: github-actions <github-actions@github.com>
2021-05-07 14:19:19 +02:00
github-actions
75317d230b 📝 Update release notes 2021-05-07 12:05:45 +00:00
Sebastián Ramírez
e662654c49 🔊 Update FastAPI People to allow better debugging (#3188) 2021-05-07 14:04:54 +02:00
Sebastián Ramírez
2a67321130 🔖 Release version 0.64.0 2021-05-07 10:15:26 +02:00
Sebastián Ramírez
8d9d2c0d3f 📝 Update release notes 2021-05-07 10:14:21 +02:00
github-actions
dc6a78c357 📝 Update release notes 2021-05-06 15:48:23 +00:00
T
73d1def114 📝 Add link to article in Russian "FastAPI: знакомимся с фреймворком" (#2564) 2021-05-06 17:47:49 +02:00
github-actions
3dc74ba29f 📝 Update release notes 2021-05-06 15:42:53 +00:00
dompatmore
d9d6031db5 📝 Add external link to blog post "Authenticate Your FastAPI App with Auth0" (#2172)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-05-06 17:42:14 +02:00
Sebastián Ramírez
6135417789 📝 Update release notes 2021-05-06 17:32:04 +02:00
github-actions
6d138f218b 📝 Update release notes 2021-05-05 18:21:32 +00:00
Austin Orr
e10a4375f9 Add support for adding multiple examples in request bodies and path, query, cookie, and header params (#1267)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-05-05 20:20:56 +02:00
github-actions
3e32eb55f0 📝 Update release notes 2021-05-04 09:03:02 +00:00
NiJia Lin
b3f139c0d9 🌐 Fix Chinese translation of Tutorial - Query Parameters, remove obsolete content (#3051) 2021-05-04 11:02:19 +02:00
github-actions
3b4c692534 📝 Update release notes 2021-05-04 09:01:17 +00:00
Sam Courtemanche
05c859f324 🌐 Add French translation for Tutorial - Background Tasks (#3098)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-05-04 11:00:43 +02:00
github-actions
48a33b0453 📝 Update release notes 2021-05-04 08:49:43 +00:00
SueNaeunYang
70746a7bf0 🌐 Fix Korean translation for docs/ko/docs/index.md (#3159) 2021-05-04 10:49:07 +02:00
github-actions
69e3c6e3d3 📝 Update release notes 2021-05-04 08:38:41 +00:00
Spike
388e5c0c25 🌐 Add Korean translation for Tutorial - Query Parameters (#2390)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-05-04 10:38:02 +02:00
github-actions
61db5ebcc2 📝 Update release notes 2021-05-04 08:28:21 +00:00
JulianMaurin
23845979ea 🌐 Add French translation for FastAPI People (#2232)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-05-04 10:27:49 +02:00
github-actions
83f7a36d05 📝 Update release notes 2021-05-04 08:25:39 +00:00
Spike
462014e296 🌐 Add Korean translation for Tutorial - Path Parameters (#2355) 2021-05-04 10:24:58 +02:00
github-actions
5da5ae5554 📝 Update release notes 2021-05-04 08:20:03 +00:00
Jérôme Fink
f3a985cb81 🌐 Add French translation for Features (#2157)
Co-authored-by: Jérôme Fink <jerome.fink@unamur.be>
2021-05-04 10:19:24 +02:00
github-actions
22528373bb 📝 Update release notes 2021-04-07 07:04:13 +00:00
github-actions[bot]
ce0ec06e8a 👥 Update FastAPI People (#3031)
Co-authored-by: github-actions <github-actions@github.com>
2021-04-07 09:03:39 +02:00
github-actions
10397ddc30 📝 Update release notes 2021-03-27 17:52:30 +00:00
Shucai.wang
6f72a27632 🌐 Add Chinese translation for Tutorial - Debugging (#2737)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-03-27 18:51:51 +01:00
Sebastián Ramírez
2783667f80 📝 Update release notes 2021-03-27 18:50:39 +01:00
github-actions
d8c1d040d4 📝 Update release notes 2021-03-27 17:39:13 +00:00
Xie Wei
7f037f1bdc 🌐 Add Chinese translation for Tutorial - Security - OAuth2 with Password (and hashing), Bearer with JWT tokens (#2642)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-03-27 18:38:33 +01:00
github-actions
f31104585f 📝 Update release notes 2021-03-27 17:36:52 +00:00
mode
5934a75ddd 🌐 Add Korean translation for Tutorial - Header Parameters (#2589)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-03-27 18:36:09 +01:00
github-actions
650abf091b 📝 Update release notes 2021-03-27 17:31:54 +00:00
Shucai.wang
66f18e9282 🌐 Add Chinese translation for Tutorial - Metadata and Docs URLs (#2559) 2021-03-27 18:31:11 +01:00
github-actions
f044f13121 📝 Update release notes 2021-03-27 17:30:24 +00:00
Spike
0250cfa398 🌐 Add Korean translation for Tutorial - First Steps (#2323)
Co-authored-by: Dahun Jeong <gnsgnsek@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-03-27 18:29:45 +01:00
github-actions
f4ce2510f3 📝 Update release notes 2021-03-27 17:28:52 +00:00
Shucai.wang
8f0a604a37 🌐 Add Chinese translation for Tutorial - CORS (Cross-Origin Resource Sharing) (#2540)
Co-authored-by: Xie Wei <ampedee@gmail.com>
2021-03-27 18:28:07 +01:00
github-actions
0f4c2b6ee0 📝 Update release notes 2021-03-27 17:26:01 +00:00
lpdswing
368d314e11 🌐 Add Chinese translation for Tutorial - Middleware (#2334)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-03-27 18:25:21 +01:00
github-actions
4e79cb0be4 📝 Update release notes 2021-03-27 17:23:26 +00:00
Spike
973595b3cb 🌐 Add Korean translation for Tutorial - Intro (#2317)
Co-authored-by: Dahun Jeong <gnsgnsek@gmail.com>
2021-03-27 18:22:50 +01:00
github-actions
fa779017d2 📝 Update release notes 2021-03-27 16:55:48 +00:00
Sebastián Ramírez
b2e27de2fc 🔧 Update top banner, point to newsletter (#3003) 2021-03-27 17:55:12 +01:00
github-actions
31a7bfd227 📝 Update release notes 2021-03-27 16:46:10 +00:00
Sebastián Ramírez
47dde41c6c 🔧 Disable sponsor WeTransfer (#3002) 2021-03-27 17:45:32 +01:00
github-actions
413a86998e 📝 Update release notes 2021-03-27 16:36:52 +00:00
Sebastián Ramírez
36721d4362 📌 Pin SQLAlchemy range, as it doesn't use SemVer (#3001) 2021-03-27 17:36:07 +01:00
github-actions
c09e950bd2 📝 Update release notes 2021-03-01 19:02:33 +00:00
Sebastián Ramírez
4d208b2b90 🎨 Add newly required type annotations for mypy (#2882)
* ⬆️ Upgrade mypy

* 🎨 Add extra type annotations, now required by mypy
2021-03-01 20:01:50 +01:00
github-actions
071c6a17dd 📝 Update release notes 2021-03-01 18:33:53 +00:00
github-actions[bot]
4ab79c679b 👥 Update FastAPI People (#2880)
Co-authored-by: github-actions <github-actions@github.com>
2021-03-01 19:33:08 +01:00
github-actions
33be5fc8ba 📝 Update release notes 2021-02-07 18:27:26 +00:00
Davide Fiocco
a7a353e1f5 📝 Fix broken link to article: Machine learning model serving in Python using FastAPI and Streamlit (#2557) 2021-02-07 19:26:44 +01:00
github-actions
c153d9b83e 📝 Update release notes 2021-02-07 18:26:07 +00:00
vjanz
2875d88ccf 📝 Add FastAPI Medium Article: Deploy a dockerized FastAPI application to AWS (#2515)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-02-07 19:25:27 +01:00
github-actions
9e0cca828d 📝 Update release notes 2021-02-07 18:19:21 +00:00
johnthagen
5dc3ec4a65 ✏ Fix typo in Tutorial - Handling Errors (#2486) 2021-02-07 19:18:37 +01:00
github-actions
bda392cba6 📝 Update release notes 2021-02-07 18:16:26 +00:00
water_lift
f22137346a 🎨 Remove internal "type: ignore", now unnecessary (#2424) 2021-02-07 19:15:43 +01:00
github-actions
f108741a82 📝 Update release notes 2021-02-07 18:14:23 +00:00
Jürgen Gmach
8433e8efe2 ✏ Fix typo in Security OAuth2 scopes (#2407) 2021-02-07 19:13:41 +01:00
github-actions
e6a1a9e193 📝 Update release notes 2021-02-07 18:06:49 +00:00
kangni
bbb22813e6 ✏ Fix typo/clarify docs for SQL (Relational) Databases (#2393)
By way of code example, I think this is a typo. btw, the tutorial is very well written.
2021-02-07 19:06:08 +01:00
github-actions
f0f8e287ec 📝 Update release notes 2021-02-07 18:02:41 +00:00
Xie Wei
0af6cbe990 🌐 Add Chinese translation for Tutorial - Bigger Applications - Multiple Files (#2453)
Co-authored-by: Shucai.wang <blt23@126.com>
2021-02-07 19:02:00 +01:00
github-actions
9e9e068762 📝 Update release notes 2021-02-07 18:01:12 +00:00
Xie Wei
9fda0149da 🌐 Add Chinese translation for Tutorial - Security - Security Intro (#2443) 2021-02-07 19:00:14 +01:00
github-actions
95a713b3e2 📝 Update release notes 2021-02-07 17:59:55 +00:00
maoyibo
2da3d62d37 🌐 Add Chinese translation for Tutorial - Header Parameters (#2412)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-02-07 18:59:12 +01:00
github-actions
7dd2e92d7e 📝 Update release notes 2021-02-07 17:52:50 +00:00
maoyibo
6d06e13284 🌐 Add Chinese translation for Tutorial - Extra Data Types (#2410)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-02-07 18:52:09 +01:00
github-actions
a2199c545b 📝 Update release notes 2021-02-07 17:47:02 +00:00
T. Tokusumi
08cbc6c8ff 🌐 Add Japanese translation for Deployment - Docker (#2312)
Co-authored-by: Taki Komiyama <39375566+komtaki@users.noreply.github.com>
Co-authored-by: Sho Nakamura <sh0nk.developer@gmail.com>
2021-02-07 18:46:22 +01:00
github-actions
f730160037 📝 Update release notes 2021-02-07 17:45:09 +00:00
T. Tokusumi
20360c207e 🌐 Add Japanese translation for Deployment - Versions (#2310)
Co-authored-by: Taki Komiyama <39375566+komtaki@users.noreply.github.com>
Co-authored-by: Sho Nakamura <sh0nk.developer@gmail.com>
2021-02-07 18:44:28 +01:00
github-actions
568a54dff2 📝 Update release notes 2021-02-07 17:43:14 +00:00
Alicrazy
91cacc9c92 🌐 Add Chinese translation for Tutorial - Cookie Parameters (#2261)
Co-authored-by: lijun <lijun@duozhuayu.net>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-02-07 18:42:34 +01:00
github-actions
b3899333f4 📝 Update release notes 2021-02-07 17:41:26 +00:00
Amit Chaudhary
6b6a310e54 📝 Add external link to "FastAPI for Flask Users" (#2280) 2021-02-07 18:40:42 +01:00
github-actions
cb2dce03c0 📝 Update release notes 2021-02-07 17:38:52 +00:00
T. Tokusumi
7122687f25 🌐 Add Japanese translation for Tutorial - Static files (#2260)
Co-authored-by: Taki Komiyama <39375566+komtaki@users.noreply.github.com>
Co-authored-by: Sho Nakamura <sh0nk.developer@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-02-07 18:38:10 +01:00
github-actions
af6fcf1413 📝 Update release notes 2021-02-07 17:32:12 +00:00
T. Tokusumi
cd8b90a5a4 🌐 Add Japanese translation for Tutorial - Testing (#2259)
Co-authored-by: Taki Komiyama <39375566+komtaki@users.noreply.github.com>
Co-authored-by: Sho Nakamura <sh0nk.developer@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-02-07 18:31:30 +01:00
github-actions
c88fb2eef0 📝 Update release notes 2021-02-07 17:26:15 +00:00
T. Tokusumi
17781e3596 🌐 Add Japanese translation for Tutorial - Debugging (#2256)
Co-authored-by: Sho Nakamura <sh0nk.developer@gmail.com>
2021-02-07 18:25:31 +01:00
github-actions
a381642558 📝 Update release notes 2021-02-07 17:24:39 +00:00
T. Tokusumi
5828043b69 🌐 Add Japanese translation for Tutorial - Middleware (#2255)
Co-authored-by: Sho Nakamura <sh0nk.developer@gmail.com>
2021-02-07 18:23:55 +01:00
github-actions
909a81f88a 📝 Update release notes 2021-02-07 17:21:27 +00:00
T. Tokusumi
faec713e0d 🌐 Add Japanese translation for Concurrency and async / await (#2058)
Co-authored-by: Taki Komiyama <39375566+komtaki@users.noreply.github.com>
Co-authored-by: Sho Nakamura <sh0nk.developer@gmail.com>
2021-02-07 18:20:43 +01:00
github-actions
60addbcdd5 📝 Update release notes 2021-02-01 14:49:57 +00:00
github-actions[bot]
a27a1bc53c 👥 Update FastAPI People (#2739)
Co-authored-by: github-actions <github-actions@github.com>
2021-02-01 15:49:09 +01:00
github-actions
41f291524d 📝 Update release notes 2021-01-19 20:13:46 +00:00
Sebastián Ramírez
6b3bc7384e 🔧 Add new Gold Sponsor Talk Python 🎉 (#2673) 2021-01-19 21:12:58 +01:00
github-actions
561bbfb5d2 📝 Update release notes 2021-01-18 15:35:35 +00:00
Sebastián Ramírez
8ce1c81398 🔧 Add new Gold Sponsor vim.so 🎉 (#2669) 2021-01-18 16:34:46 +01:00
github-actions
cb40e27db2 📝 Update release notes 2021-01-09 21:24:44 +00:00
Sebastián Ramírez
f031973848 🔧 Add FastAPI user survey banner (#2623)
* 🔧 Add FastAPI user survey banner

* 🔧 Make FastAPI user survey banner open new tab
2021-01-09 22:24:03 +01:00
github-actions
307d37d85c 📝 Update release notes 2021-01-09 21:11:58 +00:00
Sebastián Ramírez
bf290fa5f0 🔧 Add new Bronze Sponsor(s) 🥉🎉 (#2622)
* 🔧 Update FastAPI People sponsors, include new Bronze Sponsor 🎉

* 📝 Update FastAPI People in Japanese
2021-01-09 22:11:15 +01:00
github-actions
26f313d524 📝 Update release notes 2021-01-09 20:55:21 +00:00
Sebastián Ramírez
73021d7261 📝 Update social links: add Discord, fix GitHub (#2621) 2021-01-09 21:54:38 +01:00
github-actions
f54fb88ad5 📝 Update release notes 2021-01-09 19:00:40 +00:00
Xie Wei
b3d2f47bc8 🌐 Add Chinese translation for Tutorial - Security - Simple OAuth2 with Password and Bearer (#2514)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-01-09 19:59:56 +01:00
github-actions
52f170b3fe 📝 Update release notes 2021-01-09 18:59:33 +00:00
T. Tokusumi
9442845ca5 🌐 Add Japanese translation for Deployment - Deta (#2314)
Co-authored-by: Taki Komiyama <39375566+komtaki@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-01-09 19:58:52 +01:00
github-actions
fe31b0caae 📝 Update release notes 2021-01-09 18:53:47 +00:00
Xie Wei
d2ca3df033 🌐 Add Chinese translation for Tutorial - Security - Get Current User (#2474) 2021-01-09 19:53:05 +01:00
github-actions
838ea752b2 📝 Update release notes 2021-01-09 18:52:30 +00:00
T. Tokusumi
2b49b8c70a 🌐 Add Japanese translation for Deployment - Manually (#2313)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-01-09 19:51:42 +01:00
github-actions
05b024d61b 📝 Update release notes 2021-01-09 18:47:49 +00:00
T. Tokusumi
c7742e3c56 🌐 Add Japanese translation for Deployment - Intro (#2309)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-01-09 19:47:08 +01:00
github-actions
4f9104ce97 📝 Update release notes 2021-01-09 18:43:08 +00:00
T. Tokusumi
07a8f7b5b5 🌐 Add Japanese translation for FastAPI People (#2254)
Co-authored-by: Taki Komiyama <39375566+komtaki@users.noreply.github.com>
2021-01-09 19:42:24 +01:00
github-actions
f2a28f4b5b 📝 Update release notes 2021-01-09 18:41:10 +00:00
atsumi
5a4a61ca67 🌐 Add Japanese translation for Advanced - Path Operation Advanced Configuration (#2124)
Co-authored-by: T. Tokusumi <41147016+tokusumi@users.noreply.github.com>
2021-01-09 19:40:27 +01:00
github-actions
71ac76c3cd 📝 Update release notes 2021-01-09 18:39:11 +00:00
T. Tokusumi
68dca8f42d 🌐 Add Japanese translation for External Links (#2070)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-01-09 19:38:20 +01:00
github-actions
a38e6f4e2c 📝 Update release notes 2021-01-09 18:33:53 +00:00
SwftAlpc
ca26f2274c 🌐 Add Japanese translation for Tutorial - Body - Updates (#1956)
Co-authored-by: T. Tokusumi <41147016+tokusumi@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: tokusumi <tksmtoms@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2021-01-09 19:33:07 +01:00
github-actions
8108cd89bb 📝 Update release notes 2021-01-09 18:28:54 +00:00
SwftAlpc
8560151090 🌐 Add Japanese translation for Tutorial - Form Data (#1943)
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>
2021-01-09 19:28:15 +01:00
github-actions
91805cdf03 📝 Update release notes 2021-01-09 18:20:10 +00:00
SwftAlpc
48cba16578 🌐 Add Japanese translation for Tutorial - Cookie Parameters (#1933)
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>
2021-01-09 19:19:26 +01:00
github-actions
7098e3b150 📝 Update release notes 2021-01-09 16:58:08 +00:00
Sebastián Ramírez
a7cc25eb11 🔧 Update FastAPI People GitHub Sponsors order (#2620) 2021-01-09 17:57:27 +01:00
github-actions
d2eb4a71ee 📝 Update release notes 2021-01-05 21:04:05 +00:00
Sebastián Ramírez
54eeb3161f 🔧 Update InvestSuite sponsor data (#2608) 2021-01-05 22:03:24 +01:00
github-actions
4fabcfa3ab 📝 Update release notes 2021-01-01 20:15:01 +00:00
github-actions[bot]
5c29daadcc 👥 Update FastAPI People (#2590)
Co-authored-by: github-actions <github-actions@github.com>
2021-01-01 21:14:17 +01:00
Sebastián Ramírez
5614b94ccc 📝 Update release notes 2020-12-20 20:18:06 +01:00
Sebastián Ramírez
e170c86412 🔖 Release version 0.63.0 2020-12-20 20:16:12 +01:00
github-actions
180bdf31ac 📝 Update release notes 2020-12-20 19:13:21 +00:00
Sebastián Ramírez
1e58a3e44c ⬆️ Upgrade Uvicorn when installing fastapi[all] to the latest version including uvloop (#2548)
* ⬆️ Upgrade Uvicorn when installing fastapi[all] to the latest version, including uvloop

* ⬆️ Relax Uvicorn version range to the minimum supported

in case anyone depends older versions somehow installed with FastAPI extras
2020-12-20 20:12:39 +01:00
Sebastián Ramírez
dfe3f614ed 📝 Update release notes 2020-12-20 19:57:11 +01:00
github-actions
97c747fe54 📝 Update release notes 2020-12-20 18:50:42 +00:00
Sebastián Ramírez
fdb6c9ccc5 Improve type annotations, add support for mypy --strict, internally and for external packages (#2547) 2020-12-20 19:50:00 +01:00
github-actions
4fdcdf341c 📝 Update release notes 2020-12-19 20:31:01 +00:00
Sebastián Ramírez
e2a6341c60 📝 Update Uvicorn installation instructions to use uvicorn[standard] (includes uvloop) (#2543) 2020-12-19 21:30:18 +01:00
github-actions
7046d80a23 📝 Update release notes 2020-12-19 19:54:43 +00:00
Sebastián Ramírez
9f89399f5e 🌐 Add docs lang selector widget (#2542)
*  Add language selector widget

* 🔧 Update script to re-generate MkDocs configs, including langs widget

* 🔧 Update languages MkDocs configs, with lang selector widget
2020-12-19 20:54:02 +01:00
github-actions
ed0fe9f369 📝 Update release notes 2020-12-19 18:55:37 +00:00
Sebastián Ramírez
6e9b771abf 🐛 Fix docs overrides directory for translations (#2541)
* 🙈 Add .gitignore files to keep overrides directories for translations to fix serving live locally during translations

* ♻️ Refactor docs scripts to handle language overrides (newsletter notification)
2020-12-19 19:54:54 +01:00
github-actions
4a93562a3d 📝 Update release notes 2020-12-19 18:17:19 +00:00
Xie Wei
3f478b7733 🌐 Add Chinese translation for Tutorial - Response Status Code (#2442)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-12-19 19:16:37 +01:00
github-actions
c660d96dce 📝 Update release notes 2020-12-19 18:06:59 +00:00
Sebastián Ramírez
6de9f5890d Remove Typer as a docs building dependency (covered by typer-cli) to fix pip resolver conflicts (#2539) 2020-12-19 19:06:19 +01:00
github-actions
a16ecf2f91 📝 Update release notes 2020-12-19 14:06:30 +00:00
vjanz
7a2c5526d4 🌐 Start translation of the documentation for the Albanian language (#2516) 2020-12-19 15:05:49 +01:00
github-actions
d6b5bc9401 📝 Update release notes 2020-12-13 15:34:30 +00:00
Sebastián Ramírez
e6f8aa8756 Add newsletter: FastAPI and friends (#2509)
*  Add newsletter: FastAPI and friends

* 🔧 Update MkDocs config for announcement

* 🔧 Update generation script to include overrides for announcements
2020-12-13 16:33:46 +01:00
github-actions
f0a14a9ab6 📝 Update release notes 2020-12-12 21:28:29 +00:00
Sebastián Ramírez
c3dbf4ef7c Add new Gold Sponsor: InvestSuite 🎉 (#2508) 2020-12-12 22:27:46 +01:00
github-actions
52dd5924d7 📝 Update release notes 2020-12-06 08:36:00 +00:00
Sebastián Ramírez
a960c42178 🔧 Add issue template configs (#2476)
🔧 Add issue template configs
2020-12-06 09:35:21 +01:00
github-actions
436b023fe4 📝 Update release notes 2020-12-03 17:38:21 +00:00
Xie Wei
f1759297c7 🌐 Add Chinese translation for Tutorial - Extra Models (#2416)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-12-03 18:36:46 +01:00
github-actions
f1ca8da6e1 📝 Update release notes 2020-12-03 17:28:44 +00:00
Xie Wei
478f157013 🌐 Add Chinese translation for Tutorial - Response Model (#2414)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-12-03 18:27:58 +01:00
github-actions
5c8b41abf2 📝 Update release notes 2020-12-03 17:08:59 +00:00
maoyibo
4236c99b7f 🌐 Add Chinese translation for Tutorial - Schema Extra Example (#2411) 2020-12-03 18:08:11 +01:00
github-actions
1a816fd6a0 📝 Update release notes 2020-12-03 17:06:04 +00:00
hard_coder
02b7d988ae 🌐 Add Korean translation for Index (#2192) 2020-12-03 18:05:19 +01:00
github-actions
1b70a1cbf6 📝 Update release notes 2020-12-03 17:01:38 +00:00
atsumi
259c55f7cd 🌐 Add Japanese translation for Advanced User Guide - Additional Status Codes (#2145)
Co-authored-by: Taki Komiyama <39375566+komtaki@users.noreply.github.com>
Co-authored-by: T. Tokusumi <41147016+tokusumi@users.noreply.github.com>
2020-12-03 18:00:54 +01:00
github-actions
6a05f1774e 📝 Update release notes 2020-12-03 16:58:32 +00:00
Sebastián Ramírez
6189aacd0f 📝 Update title for Deta tutorial (#2466) 2020-12-03 17:57:50 +01:00
github-actions
9e6b069c09 📝 Update release notes 2020-12-02 07:00:39 +00:00
github-actions[bot]
6ffc8a547f 👥 Update FastAPI People (#2454)
Co-authored-by: github-actions <github-actions@github.com>
2020-12-01 19:12:45 +01:00
Sebastián Ramírez
51e920e2fc 🔖 Release version 0.62.0 2020-11-29 19:36:38 +01:00
Sebastián Ramírez
c27b9dcf9d 📝 Update release notes, add breaking changes details 2020-11-29 19:35:10 +01:00
Sebastián Ramírez
c7e137c6e0 📝 Update release notes 2020-11-29 19:17:35 +01:00
github-actions
7e4d7fe895 📝 Update release notes 2020-11-29 18:04:51 +00:00
Sebastián Ramírez
2c57ea57bf 🔧 Update TestDriven link to course in sponsors (#2435) 2020-11-29 19:04:27 +01:00
Sebastián Ramírez
be7d15ce3a 📝 Update release notes 2020-11-29 18:55:48 +01:00
github-actions
afc2bb0801 📝 Update release notes 2020-11-29 17:32:46 +00:00
Sebastián Ramírez
313bbe802f Add support for shared/top-level parameters (dependencies, tags, etc) (#2434)
*  Add Default and DefaultPlaceholder data structures

to handle defaults and overrides

*  Add utils to get values by priority handling DefaultPlaceholders

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

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

* ♻️ Update openapi utils to handle DefaultPlaceholder for response_class

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

and showcase them in APIRouter, FastAPI, include_router

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

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

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

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

*  Update/increase tests for Bigger Applications including shared parameters

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

*  Add tests for internal DefaultPlaceholder

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

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

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

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

* ⬆️ Install Material for MkDocs Insiders on CI

* 🔧 Update MkDocs configs to use Material for MkDocs Insiders

*  Use the lightbulb because it looks nice 💡

* 💚 Fix GitHub Action workflow syntax for building docs

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

* Apply suggestions from code review

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

* Apply suggestions from code review

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

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

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

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

* 📝 Add docs for deploying on Deta

* 🍱 Add Deta docs screenshots

* ♻️ Refactor and separate deployment docs

* 📝 Update internal docs links to Deployment

* 📝 Update links in Deta tutorial

* 🍱 Update sponsors images

* 🔧 Use sponsors data from YAML

* 📝 Update sponsors in languages docs

*  Update docs generation scripts

*  Update README.md testing

* 📝 Update main README

* 🔧 Update fastapi-people action handling individual sponsors

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

* 🔥 Remove replaced GitHub Action get-artifact

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

* 🔥 Remove commented backup configs in Preview Docs GitHub Action

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

* 🔧 Use predefined name for docs artifacts for previews

*  Add new GitHub Action Comment Docs Preview in PR

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

*  Add first version of FastAPI People GitHub action code

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

* 👷 Add GitHub Action workflow for FastAPI People

* 📝 Add FastAPI People to docs

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

* ⬆️ Require Pydantic >=1.0.0 in requirements
2020-08-09 22:17:08 +02:00
Sebastián Ramírez
3390182fc9 📝 Update release notes 2020-08-09 17:04:35 +02:00
Sebastián Ramírez
912a43ee3d 📝 Add link to TestDriven.io course in docs (#1860) 2020-08-09 17:02:51 +02:00
Sebastián Ramírez
4020304945 📝 Update release notes 2020-08-09 16:43:07 +02:00
Elliana May
0a2fc78fea ✏️ Update docs to remove gender-specific references (#1824)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-08-09 16:35:44 +02:00
Sebastián Ramírez
b91acfb457 📝 Update release notes 2020-08-09 15:58:58 +02:00
Nik
b9a0179a03 Add support for injecting HTTPConnection (#1827) 2020-08-09 15:56:41 +02:00
Rupsi Kaushik
5ed48ccdc8 Export WebSocketDisconnect and add example handling disconnections to docs (#1822)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-08-09 15:52:19 +02:00
Sebastián Ramírez
f32d67c8b9 📝 Update release notes 2020-08-09 13:12:09 +02:00
manlix
0752c7242d 🔊 Fix empty log message in docs example about raised exceptions (#1815) 2020-08-09 13:10:33 +02:00
Sebastián Ramírez
be855c696b 📝 Update release notes 2020-08-09 12:56:09 +02:00
Nima Mashhadi M. Reza
da9b5201c4 🔧 Add Flake8 linting (#1774)
Co-authored-by: nimashadix <nimashadix@pop-os.localdomain>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-08-09 12:54:05 +02:00
Sebastián Ramírez
4daa6ef4e4 📝 Update release notes 2020-08-09 11:08:29 +02:00
Sebastián Ramírez
4ad7c55618 💚 Disable Gitter notification as it's currently broken (#1853)
...no idea why yet. 😔
2020-08-08 20:43:31 +02:00
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
Sebastián Ramírez
f7eea768f6 🔖 Release 0.54.2 2020-05-16 21:00:28 +02:00
Sebastián Ramírez
53d316f706 📝 Update release notes 2020-05-16 20:56:58 +02:00
Alvaro Pernas
741de7f927 🌐 Add Spanish translation for Concurrency and async / await (#1290)
* final touches to async section ES translation

* minor fixes

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* Update docs/es/docs/async.md

Co-Authored-By: Camila Gutierrez <mariacamilagl@users.noreply.github.com>

* 📝 Update async/await docs in EN with emojis

* 📝 Update wording, format, and emojis for async/await in ES

* 🔧 Add async.md to MkDocs for Spanish

Co-authored-by: Camila Gutierrez <mariacamilagl@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-05-16 20:53:40 +02:00
Sebastián Ramírez
16b3669adf 📝 Update release notes 2020-05-16 18:03:17 +02:00
Donghui Wang
c5807fdaa4 🔥 Remove vote link (#1289)
remove 'Vote to include FastAPI in awesome-python', because the PR was closed
2020-05-16 18:02:05 +02:00
Sebastián Ramírez
897b7d1b99 📝 Update release notes 2020-05-16 17:47:26 +02:00
Sebastián Ramírez
409264960e Allow disabling docs UIs by disabling OpenAPI (#1421)
*  Allow disabling docs UIs by disabling openapi_url

* 📝 Add docs for disabling OpenAPI and docs in prod or other environments

*  Add tests for disabling OpenAPI and docs
2020-05-16 17:45:12 +02:00
Sebastián Ramírez
cfb72eec5a 📝 Update release notes 2020-05-16 15:41:21 +02:00
Fabio Serrao
778822bd9a 🌐 Add Portuguese translation for benchmarks (#1274)
* Translation benchmarks

* Update docs/pt/docs/benchmarks.md

Co-Authored-By: Marcos Monteiro <marcosmmb90@gmail.com>

* Update docs/pt/docs/benchmarks.md

Co-Authored-By: Marcos Monteiro <marcosmmb90@gmail.com>

* Update docs/pt/docs/benchmarks.md

Co-Authored-By: Marcos Monteiro <marcosmmb90@gmail.com>

* Update docs/pt/docs/benchmarks.md

Co-Authored-By: Marcos Monteiro <marcosmmb90@gmail.com>

* Update docs/pt/docs/benchmarks.md

Co-Authored-By: Marcos Monteiro <marcosmmb90@gmail.com>

* Update docs/pt/docs/benchmarks.md

Co-Authored-By: Marcos Monteiro <marcosmmb90@gmail.com>

* Update docs/pt/docs/benchmarks.md

Co-Authored-By: Marcos Monteiro <marcosmmb90@gmail.com>

* Update docs/pt/docs/benchmarks.md

Co-Authored-By: Marcos Monteiro <marcosmmb90@gmail.com>

* Update docs/pt/docs/benchmarks.md

Co-Authored-By: Marcos Monteiro <marcosmmb90@gmail.com>

* 🔧 Include benchmark translation in MkDocs for Portuguese

Co-authored-by: Marcos Monteiro <marcosmmb90@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-05-16 15:37:57 +02:00
Sebastián Ramírez
cfd2c3017f 📝 Update release notes 2020-05-16 15:31:21 +02:00
Marcos Monteiro
caed37a08f 🌐 Add Portuguese translation for the tutorial/index page (#1259)
* Translate tutorial/index.md to Portuguese

* ✏️ Update capitalization

* 🔧 Update docs section title in Portuguese

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-05-16 15:28:26 +02:00
Sebastián Ramírez
4c1b54e209 📝 Update release notes 2020-05-16 15:18:18 +02:00
Sebastián Ramírez
e4f0947821 Allow Unicode in MkDocs for translations instead of escaped chars (#1419) 2020-05-16 15:17:24 +02:00
Sebastián Ramírez
22e858f65c 📝 Update release notes 2020-05-16 15:01:10 +02:00
Juan Funez
046d6b7fa0 🌐 Add Spanish translation for advanced/index.md (#1250)
* spanish translation for advanced/index.md

* Ajustes sugeridos

* ✏️ Capitalize docs title

* 🔧 Add config to MkDocs for spanish

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-05-16 14:58:00 +02:00
Sebastián Ramírez
89f36371b9 📝 Update release notes 2020-05-16 14:48:56 +02:00
Marcos Monteiro
406b3ac805 🌐 Add Portuguese translation for the history-design-future page (#1249)
* Translate history-design-future.md to Portuguese

* Update docs/pt/docs/history-design-future.md

Co-Authored-By: Cássio Botaro <cassiobotaro@gmail.com>

* 📝 Capitalize title

Co-authored-by: Cássio Botaro <cassiobotaro@gmail.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-05-16 14:46:49 +02:00
Sebastián Ramírez
f71ba8885e 📝 Update release notes 2020-05-16 14:39:54 +02:00
Marcos Monteiro
121e87b3e0 🌐 Add Portuguese translation for Features (#1248)
* Translate features.md file to Portuguese

* Changes word of features.md translation to Portuguese

* Fixing typos and bad wording

Thanks @Serrones for the kind review
2020-05-16 14:37:17 +02:00
Sebastián Ramírez
2d013b8340 📝 Update release notes 2020-05-16 13:06:28 +02:00
Sebastián Ramírez
761e5ff01d 🐛 Fix Spanish MkDocs title 2020-05-16 13:05:21 +02:00
MartinEliasQ
9812684178 🌐 Add Spanish translation for the tutorial-user-guide index page (#1244)
* Spanish translation for the tutorial-user-guide index page

* Improve some parts of the text in terms of writing

* Change the wording to keep the documentation consistent.

* 📝 Add small wording and consistency changes

* 🎨 Apply the same consistency changes to EN 🤷

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-05-16 13:02:20 +02:00
Sebastián Ramírez
f7a87cd6ba 📝 Update release notes 2020-05-16 12:47:44 +02:00
Ikkyu
f67bc3ffe8 🌐 Add Chinese translations for docs: deployment.md (#1203)
* Add new language of docs: zh

* Add deployment.md Chinese trans

* add "or"

* rm index.md

* updates Chinese translations of deployement.md

* update translations of deployment.md

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-05-16 12:45:04 +02:00
Sebastián Ramírez
dff644abe0 📝 Update release notes 2020-05-16 12:38:13 +02:00
Xie Wei
fc7b4ab880 🌐 Add Chinese translation for tutorial intro doc (#1202)
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-05-16 12:32:31 +02:00
Sebastián Ramírez
1d0f909ca5 📝 Update release notes 2020-05-16 12:21:06 +02:00
Dustyposa
a0cdbe449b 🌐 Add translation of features.md to Chinese (#1192)
* translation features.md to Chinese

* update review data

* :DOCS: update with review

* 🔥 Remove double link in build mkdocs.yml for other languages

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-05-16 12:18:04 +02:00
Sebastián Ramírez
44bd64d797 📝 Update release notes 2020-05-16 12:04:32 +02:00
Xie Wei
bfa78db458 🌐 Add Chinese translation for index docs (#1191)
* Add Chinese tranlation for docs/index.md

* Fix syntax issue

* Update resource address of zh docs

* Optimize typography in zh docs

* improve translations

Co-authored-by: Waynerv <wei.xie@woqutech.com>
2020-05-16 11:58:10 +02:00
Sebastián Ramírez
4e77737a3f 📝 Update release notes 2020-04-18 17:57:50 +02:00
Sebastián Ramírez
d03c197c80 📝 Update project generation docs (#1287) 2020-04-18 17:56:35 +02:00
Sebastián Ramírez
06e42a4e5d 📝 Update release notes 2020-04-11 19:22:35 +02:00
Camila Gutierrez
bd1e85a8d3 📝 Add Spanish translation for the Python Types Intro page (#1237)
* Spanish translation Python Types Intro page

* 📝 Fix tuple docs in Types intro

* ✏️ Fix typos and wording nitpicks

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-04-11 19:20:32 +02:00
Sebastián Ramírez
506d5dce39 📝 Update release notes 2020-04-11 18:49:52 +02:00
Camila Gutierrez
a7b4c73663 📝 Add Spanish translation for the Features page (#1220)
* Spanish translation for the Features page

* ✏️ Fix small typos and wording nitpicks

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-04-11 18:46:46 +02:00
Sebastián Ramírez
d4f3ca1c1b 🔖 Release 0.54.1 2020-04-08 07:51:26 +02:00
Sebastián Ramírez
471d703611 📝 Update release notes 2020-04-08 07:50:30 +02:00
Sebastián Ramírez
a46bbc54cd Update database setup for tests (#1226)
* 🗃️ Update database setup for tests

*  Add pragmas and update db handling for tests
2020-04-08 07:41:53 +02:00
Sebastián Ramírez
a4405bbed2 📝 Update release notes 2020-04-08 06:39:40 +02:00
Samuel Colvin
e9b189e9f2 Improve test debugging (#1222) 2020-04-08 06:37:38 +02:00
Sebastián Ramírez
483bce3ae1 ⬆️ Upgrade to MkDocs Material 5 and update docs scripts (#1225)
* ⬆️ Upgrade mkdocs.yml configs for MkDocs Material 5

*  Update docs.py to always update mkdocs.yml

* 🌐 Update mkdocs.yml for translations

* 🔧 Update MkDocs config

*  Add tabs for alternative options

* ⬆️ Update termynal setup with new CSS classes

* 🔧 Sync / Update mkdocs.yml for languages
2020-04-08 06:25:01 +02:00
Sebastián Ramírez
7372f6ba11 🔖 Release version 0.54.0 2020-04-05 16:50:16 +02:00
Sebastián Ramírez
8d92557e53 📝 Update relase notes 2020-04-05 16:47:33 +02:00
Mickey Pashov
c56342bf79 ✏️ Fix minor grammatical mistakes in the async docs (#1188)
* Fix minor grammatical mistakes in the async docs.

* ✏️ Update wording and clarify with emojis

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-04-05 16:46:22 +02:00
Harsha Laxman
07e094fd50 📝 Add note about Alembic in project generator in SQL docs (#1183)
* Update sql-databases alembic docs

Was helpful to refer to the full-stack project when integrating alembic into my own project

* 📝 Update Alembic note in docs

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-04-05 15:15:39 +02:00
Sebastián Ramírez
1cc30de32f 📝 Update release notes 2020-04-05 15:07:00 +02:00
voegtlel
3397d4d69a Implement response_model_exclude_defaults and response_model_exclude_none (#1166)
* Implemented response_model_exclude_defaults and response_model_exclude_none to be compatible pydantic options.

* 🚚 Rename and invert include_none to exclude_none to keep in sync with Pydantic

Co-authored-by: Lukas Voegtle <lukas.voegtle@sick.de>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-04-05 15:04:46 +02:00
Sebastián Ramírez
766157bfb4 📝 Update release notes 2020-04-05 13:57:45 +02:00
duganchen
d96223460b 📝 Add an example of setting up a test database (#1144)
* Add an example of setting up a test database.

* 📝 Add/update docs for testing a DB with dependency overrides

* 🔧 Update test script, remove line removing test file as it is removed during testing

*  Update testing coverage pragma

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-04-05 13:53:09 +02:00
Sebastián Ramírez
fd99dfc95b 📝 Update release notes 2020-04-04 22:38:17 +02:00
Sebastián Ramírez
10fb7ace04 📝 Update contributing guidelines to review translation PRs (#1215) 2020-04-04 22:36:10 +02:00
Sebastián Ramírez
a1a19b103c 📝 Update release notes 2020-04-04 22:16:12 +02:00
Sebastián Ramírez
5c111caf40 📝 Update release notes 2020-04-04 22:14:55 +02:00
Gao Chao
651ee5e4d2 🎨 Update log style in main page, for GitHub Markdown compatibility (#1200)
* Update README.md

fix string format

* 🎨 Update log style in main page, for GitHub Markdown compatibility

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-04-04 22:13:55 +02:00
Cássio Botaro
c398ac87d9 🙈 Add Python venv "env" to gitignore (#1212) 2020-04-04 22:03:17 +02:00
Cássio Botaro
0a77c613b0 🌐 Add new language on docs: pt (#1210) 2020-04-04 22:01:19 +02:00
Sebastián Ramírez
70bc469373 📝 Update release notes 2020-04-04 21:39:52 +02:00
Sebastián Ramírez
b76334f544 📝 Settings using lru_cache (#1214)
*  Update settings examples to use lru_cache

* 📝 Update docs for Settings, using @lru_cache

* 🎨 Update lru_cache colors to show difference in stored values
2020-04-04 21:39:15 +02:00
Sebastián Ramírez
14b467db06 📝 Update release notes 2020-04-02 07:03:00 +02:00
Camila Gutierrez
3a0c22ce7d 🌐 Translate index to Spanish (#1201) 2020-04-02 07:00:50 +02:00
Sebastián Ramírez
3b7e4e0544 📝 Update release notes 2020-04-02 06:59:19 +02:00
alexmitelman
d4d5b21b2e 📝 Add documentation about settings and env vars (#1118)
* Add doc and example for env var config

* Syntax highlight for .env file

* Add test for configuration docs

* 📝 Update settings docs, add more examples

*  Add tests for settings

* 🚚 Rename "Application Configuration" to "Metadata and Docs URLs"

to disambiguate between that and settings

* 🔥 Remove replaced example file

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-04-02 06:55:20 +02:00
Sebastián Ramírez
6e1cd45a46 🔖 Release version 0.53.2 2020-03-30 21:49:50 +02:00
Sebastián Ramírez
b86d130eb6 📝 Update release notes 2020-03-30 21:47:11 +02:00
Toan Vuong
90afc72e64 🐛 Fix automatic embedding with dependencies and sub-dependencies (#1079)
* Handle automatic embedding with Depends

* 🐛 Fix body embeds for sub-dependencies and simplify implementation

*  Add/update tests for body embeds in dependencies

* 👷 Trigger Travis

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-03-30 21:44:43 +02:00
Sebastián Ramírez
042c697b6b 📝 Update release notes 2020-03-30 20:49:24 +02:00
amitlissack
02441ff031 🐛 Fix dependency overrides in WebSockets (#1122)
* add tests to test_ws_router to test dependencies and dependency overrides.

* supply dependency_overrides_provider to APIWebSocketRoute upon creation
2020-03-30 20:45:05 +02:00
Sebastián Ramírez
210af1fd3d 📝 Update release notes 2020-03-30 20:42:46 +02:00
Sebastián Ramírez
06eaa32bf0 🔧 Update docs script to make sure languages are always sorted (#1189) 2020-03-30 20:41:50 +02:00
Sebastián Ramírez
4f88a5fddb 📝 Update release notes 2020-03-30 20:26:07 +02:00
Ikkyu
eb6be1d725 💬 Add new language of docs: zh (#1187) 2020-03-30 20:14:58 +02:00
Sebastián Ramírez
1d99681fd4 📝 Update release notes 2020-03-30 12:01:30 +02:00
Sebastián Ramírez
618be44023 🔧 Add .env to git, to simplify VS Code development 2020-03-30 12:00:55 +02:00
Sebastián Ramírez
544afaff97 📝 Add docs for adding example to schema (#1185) 2020-03-30 11:58:48 +02:00
Sebastián Ramírez
e6b3b994be 🔖 Release version 0.53.1 2020-03-29 22:08:54 +02:00
Sebastián Ramírez
67f148ff83 📝 Update release notes 2020-03-29 22:06:02 +02:00
Sebastián Ramírez
6c34600599 🐛 Fix include docs example file (#1182) 2020-03-29 22:05:24 +02:00
John Paton
016a4b7491 📝 Add documentation of example kwarg of Field (#1106)
* Add documentation of example kwarg of Field

* 📝 Update info about schema examples

* 🚚 Move example file to new directory

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-03-29 21:43:31 +02:00
Sebastián Ramírez
be21b74ad5 📝 Update release notes 2020-03-29 19:28:53 +02:00
voegtlel
0f152b4e97 🐛 Check already cloned fields in create_cloned_field to support recursive models (#1164)
* FIX: #894
Include recursion check for create_cloned_field.
Added test for recursive model.

* ♻️ Refactor and format create_cloned_field()

Co-authored-by: Lukas Voegtle <lukas.voegtle@sick.de>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-03-29 19:26:29 +02:00
Sebastián Ramírez
0d165d1efa 📝 Update release notes 2020-03-29 18:52:33 +02:00
YangQuan
9d54215a3a 📝 Add example of Pycharm in tutorial/debugging.md (#1096)
* add example of pycharm in tutorial/debugging.md

* 📝 Update PyCharm debug instructions and screenshot

* 🚚 Move image to new location in docs

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-03-29 18:50:29 +02:00
Sebastián Ramírez
8ab916baed 📝 Update release notes 2020-03-29 17:53:49 +02:00
Paul-Louis NECH
c83c50b27d ✏️ Fix typo (#1148) 2020-03-29 17:51:58 +02:00
Sebastián Ramírez
c2ad214a84 📝 Update release notes 2020-03-29 17:05:03 +02:00
Sebastián Ramírez
459f0e11e5 🏁 Update Windows development environment and tests (#1179)
* 🏁 Fix ./scripts/docs.py encoding for Windows

* 🔥 Remove ujson from tests as it prevents Windows development

It's still tested by Starlette anyway

* 📝 Update development instructions for Windows

* 🎨 Update format for WSGIMiddleware example

*  Update tests to run on Windows
2020-03-29 17:04:04 +02:00
Sebastián Ramírez
56e43ba204 🔖 Release version 0.53.0 2020-03-27 17:56:41 +01:00
Sebastián Ramírez
10485cad5a 📝 Update release notes 2020-03-27 17:52:33 +01:00
Sebastián Ramírez
53a7798e58 🎨 Update badge for coverage (#1175)
from shields.io, as Codecov's one shows coverage for the last PR from a fork at master
2020-03-27 17:51:58 +01:00
Sebastián Ramírez
372ed58677 📝 Update release notes 2020-03-27 17:33:51 +01:00
Michael Oliver
3f8bfd62b7 Add orjson to pip install fastapi[all] (#1161) 2020-03-27 17:32:35 +01:00
Sebastián Ramírez
02a6fcad98 📝 Update release notes 2020-03-27 17:29:11 +01:00
Ari Bajo
651ced68bf 🐛 Fix GZipMiddleware code block linking to TrustedHostMiddleware in docs (#1138) 2020-03-27 17:27:57 +01:00
Sebastián Ramírez
670b64360d 📝 Update release notes 2020-03-27 17:20:01 +01:00
adg-mh
1f53fef70a ✏️ Update doc string with correct class name (#1126) 2020-03-27 17:18:23 +01:00
Sebastián Ramírez
d1f067dc5b 📝 Update release notes 2020-03-27 17:16:45 +01:00
Tomoya Yoshioka
15241b53a8 📝 Clarify function name in example (#1121) 2020-03-27 17:15:26 +01:00
Sebastián Ramírez
38fd8a674b 📝 Update release notes 2020-03-27 17:04:25 +01:00
Ben
bd37d8d04f 📝 Add new external link (#1112)
* Added new external link

I added an article in which I briefly explain how to build an Apache Kafka producer / consumer with FastAPI and aiokafka.

* 📝 Update format

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-03-27 17:02:18 +01:00
Sebastián Ramírez
bc99ad0ad1 📝 Update release notes 2020-03-27 16:21:28 +01:00
juhovh-aiven
aea04ee32e 🐛 Fix exclude_unset and aliases in response model validation (#1074)
* Fix exclude_unset and aliases in response model validation.

*  Use by_alias from param 🤷

Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-03-27 16:19:17 +01:00
Sebastián Ramírez
869c7389e2 📝 Update release notes 2020-03-27 15:34:16 +01:00
Aakash Nand
2738df3801 Add Gitter chat to docs (#1061)
* implemented chat feature using sidecar from starlette docs

* 🔥 Use external Gitter sidecar JS

*  Re-implement Gitter chat after multi-lang

* 🔥 Remove moved file

Co-authored-by: Aakash Nand <aakashnand@nttv6.jp>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
2020-03-27 15:32:15 +01:00
Sebastián Ramírez
433d7862ea 📝 Update release notes 2020-03-27 10:21:40 +01:00
Sebastián Ramírez
7625e1e386 📝 Update and simplify translations docs (#1171) 2020-03-27 10:20:39 +01:00
Sebastián Ramírez
53e773a2e1 📝 Update release notes 2020-03-26 22:24:36 +01:00
Camila Gutierrez
c13b54ad0e 🏁 Change docs address to localhost for Windows (#1169) 2020-03-26 22:22:34 +01:00
Sebastián Ramírez
71c2abb41d 📝 Update release notes 2020-03-26 20:13:03 +01:00
Sebastián Ramírez
6205935323 Add support for docs translations (#1168)
* 🌐 Refactor file structure to support internationalization

*  Update tests changed after i18n

* 🔀 Merge Typer style from master

* 🔧 Update MkConfig with Typer-styles

* 🎨 Format mkdocs.yml with cannonical form

* 🎨 Format mkdocs.yml

* 🔧 Update MkDocs config

*  Add docs translation scripts dependencies

*  Add Typer scripts to handle translations

*  Add missing translation snippet to include

*  Update contributing docs, add docs for translations

* 🙈 Add docs_build to gitignore

* 🔧 Update scripts with new locations and docs scripts

* 👷 Update docs deploy action with translations

* 📝 Add note about languages not supported in the theme

*  Add first translation, for Spanish
2020-03-26 20:09:53 +01:00
Sebastián Ramírez
5fd5b6e72d 📝 Update release notes 2020-03-24 20:39:47 +01:00
Sebastián Ramírez
faf88cea0b 🎨 Update terminal examples and Typer note (#1139)
* 🎨 Update terminal examples with Termynal

* 🍱 Add Termynal scripts and styles from Typer for terminal examples
2020-03-19 14:39:29 +01:00
Sebastián Ramírez
025b38df40 🔖 Release version 0.52.0 2020-03-01 22:34:38 +01:00
Sebastián Ramírez
ac60cba75f 📝 Update release notes 2020-03-01 22:33:11 +01:00
Sebastián Ramírez
94ee932351 Add ORJSONResponse (#1065)
*  Add ORJSONResponse

* 📝 Add tutorial using ORJSONResponse

*  Add test for ORJSONResponse

* 📝 Update index.md
2020-03-01 22:30:58 +01:00
Sebastián Ramírez
cf760d6802 🔖 Release version 0.51.0 2020-03-01 22:02:51 +01:00
Sebastián Ramírez
c65fdc4bed 📝 Update release notes 2020-03-01 21:58:36 +01:00
Sebastián Ramírez
0ac9b3ee5c Re-export utils from Starlette (#1064)
*  Re-export main features used from Starlette to simplify developer's code

* ♻️ Refactor Starlette exports

* ♻️ Refactor tutorial examples to use re-exported utils from Starlette

* 📝 Add examples for all middlewares

* 📝 Add new docs for middlewares

* 📝 Add examples for custom responses

* 📝 Extend docs for custom responses

* 📝 Update docs and add notes explaining re-exports from Starlette everywhere

* 🍱 Update screenshot for HTTP status

* 🔧 Update MkDocs config with new content

* ♻️ Refactor tests to use re-exported utils from Starlette

*  Re-export WebSocketDisconnect from Starlette for tests

*  Add extra tests for extra re-exported middleware

*  Add tests for re-exported responses from Starlette

*  Add docs about mounting WSGI apps

*  Add Flask as a dependency to test WSGIMiddleware

*  Test WSGIMiddleware example
2020-03-01 21:49:20 +01:00
Sebastián Ramírez
f2bd2c44e2 🔖 Release version 0.50.0 2020-02-29 21:49:09 +01:00
Sebastián Ramírez
f0beab1778 📝 Update release notes 2020-02-29 21:48:11 +01:00
Sebastián Ramírez
95f2dc065e 📝 Add link to the Release Notes from the section about pinning versions for deployment (#1058) 2020-02-29 21:47:46 +01:00
Sebastián Ramírez
4e8080f290 📌 Upgrade Starlette version (#1057) 2020-02-29 21:28:23 +01:00
Sebastián Ramírez
fbbed6fe81 📝 Update release notes 2020-02-29 19:22:08 +01:00
Sebastián Ramírez
2d5a5d0d9e 📝 Add docs about pinning versions for deployment (#1056) 2020-02-29 19:20:18 +01:00
1268 changed files with 89626 additions and 7230 deletions

5
.flake8 Normal file
View File

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

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.

4
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,4 @@
blank_issues_enabled: false
contact_links:
- name: Security Contact
about: Please report security vulnerabilities to security@tiangolo.com

View File

@@ -0,0 +1,181 @@
name: Feature Request
description: Suggest an idea or ask for a feature that you would like to have in FastAPI
labels: [enhancement]
body:
- type: markdown
attributes:
value: |
Thanks for your interest in FastAPI! 🚀
Please follow these instructions, fill every question, and do every step. 🙏
I'm asking this because answering questions and solving problems in GitHub issues is what consumes most of the 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, the [FastAPI Experts](https://fastapi.tiangolo.com/fastapi-people/#experts), 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 😅).
By asking questions in a structured way (following this) it will be much easier to help you.
And there's a high chance that you will find the solution along the way and you won't even have to submit it and wait for an answer. 😎
As there are too many issues with questions, I'll have to close the incomplete ones. That will allow me (and others) to focus on helping people like you that follow the whole process and help us help you. 🤓
- type: checkboxes
id: checks
attributes:
label: First Check
description: Please confirm and check all the following options.
options:
- label: I added a very descriptive title to this issue.
required: true
- label: I used the GitHub search to find a similar issue and didn't find it.
required: true
- label: I searched the FastAPI documentation, with the integrated search.
required: true
- label: I already searched in Google "How to X in FastAPI" and didn't find any information.
required: true
- label: I already read and followed all the tutorial in the docs and didn't find an answer.
required: true
- label: I already checked if it is not related to FastAPI but to [Pydantic](https://github.com/samuelcolvin/pydantic).
required: true
- label: I already checked if it is not related to FastAPI but to [Swagger UI](https://github.com/swagger-api/swagger-ui).
required: true
- label: I already checked if it is not related to FastAPI but to [ReDoc](https://github.com/Redocly/redoc).
required: true
- type: checkboxes
id: help
attributes:
label: Commit to Help
description: |
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.
options:
- label: I commit to help with one of those options 👆
required: true
- type: textarea
id: example
attributes:
label: Example Code
description: |
Please add a self-contained, [minimal, reproducible, example](https://stackoverflow.com/help/minimal-reproducible-example) with your use case.
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.
placeholder: |
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
render: python
validations:
required: true
- type: textarea
id: description
attributes:
label: Description
description: |
What is your feature request?
Write a short description telling me what you are trying to solve and what you are currently doing.
placeholder: |
* 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.
validations:
required: true
- type: textarea
id: wanted-solution
attributes:
label: Wanted Solution
description: |
Tell me what's the solution you would like.
placeholder: |
I would like it to have a `teleport_to_moon` parameter that defaults to `False`, and can be set to `True` to teleport me.
validations:
required: true
- type: textarea
id: wanted-code
attributes:
label: Wanted Code
description: Show me an example of how you would want the code to look like.
placeholder: |
from fastapi import FastAPI
app = FastAPI()
@app.get("/", teleport_to_moon=True)
def read_root():
return {"Hello": "World"}
render: python
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Alternatives
description: |
Tell me about alternatives you've considered.
placeholder: |
To wait for Space X moon travel plans to drop down long after they release them. But I would rather teleport.
- type: dropdown
id: os
attributes:
label: Operating System
description: What operating system are you on?
multiple: true
options:
- Linux
- Windows
- macOS
- Other
validations:
required: true
- type: textarea
id: os-details
attributes:
label: Operating System Details
description: You can add more details about your operating system here, in particular if you chose "Other".
- type: input
id: fastapi-version
attributes:
label: FastAPI Version
description: |
What FastAPI version are you using?
You can find the FastAPI version with:
```bash
python -c "import fastapi; print(fastapi.__version__)"
```
validations:
required: true
- type: input
id: python-version
attributes:
label: Python Version
description: |
What Python version are you using?
You can find the Python version with:
```bash
python --version
```
validations:
required: true
- type: textarea
id: context
attributes:
label: Additional Context
description: Add any additional context information or screenshots you think are useful.

View File

@@ -1,26 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: "[FEATURE]"
labels: enhancement
assignees: ''
---
### Is your feature request related to a problem
Is your feature request related to a problem?
Add a clear and concise description of what the problem is. Ex. I want to be able to [...] but I can't because [...]
### The solution you would like
Add a clear and concise description of what you want to happen.
### Describe alternatives you've considered
Add a clear and concise description of any alternative solutions or features you've considered.
### Additional context
Add any other context or screenshots about the feature request here.

View File

@@ -1,24 +0,0 @@
---
name: Question
about: Ask a question
title: "[QUESTION]"
labels: question
assignees: ''
---
### First check
* [ ] 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.
### Description
How can I [...]?
Is it possible to [...]?
### Additional context
Add any other context or screenshots about the feature request here.

146
.github/ISSUE_TEMPLATE/question.yml vendored Normal file
View File

@@ -0,0 +1,146 @@
name: Question or Problem
description: Ask a question or ask about a problem
labels: [question]
body:
- type: markdown
attributes:
value: |
Thanks for your interest in FastAPI! 🚀
Please follow these instructions, fill every question, and do every step. 🙏
I'm asking this because answering questions and solving problems in GitHub issues is what consumes most of the 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, the [FastAPI Experts](https://fastapi.tiangolo.com/fastapi-people/#experts), 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 😅).
By asking questions in a structured way (following this) it will be much easier to help you.
And there's a high chance that you will find the solution along the way and you won't even have to submit it and wait for an answer. 😎
As there are too many issues with questions, I'll have to close the incomplete ones. That will allow me (and others) to focus on helping people like you that follow the whole process and help us help you. 🤓
- type: checkboxes
id: checks
attributes:
label: First Check
description: Please confirm and check all the following options.
options:
- label: I added a very descriptive title to this issue.
required: true
- label: I used the GitHub search to find a similar issue and didn't find it.
required: true
- label: I searched the FastAPI documentation, with the integrated search.
required: true
- label: I already searched in Google "How to X in FastAPI" and didn't find any information.
required: true
- label: I already read and followed all the tutorial in the docs and didn't find an answer.
required: true
- label: I already checked if it is not related to FastAPI but to [Pydantic](https://github.com/samuelcolvin/pydantic).
required: true
- label: I already checked if it is not related to FastAPI but to [Swagger UI](https://github.com/swagger-api/swagger-ui).
required: true
- label: I already checked if it is not related to FastAPI but to [ReDoc](https://github.com/Redocly/redoc).
required: true
- type: checkboxes
id: help
attributes:
label: Commit to Help
description: |
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.
options:
- label: I commit to help with one of those options 👆
required: true
- type: textarea
id: example
attributes:
label: Example Code
description: |
Please add a self-contained, [minimal, reproducible, example](https://stackoverflow.com/help/minimal-reproducible-example) with your use case.
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.
placeholder: |
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
render: python
validations:
required: true
- type: textarea
id: description
attributes:
label: Description
description: |
What is the problem, question, or error?
Write a short description telling me what you are doing, what you expect to happen, and what is currently happening.
placeholder: |
* Open the browser and call the endpoint `/`.
* It returns a JSON with `{"Hello": "World"}`.
* But I expected it to return `{"Hello": "Sara"}`.
validations:
required: true
- type: dropdown
id: os
attributes:
label: Operating System
description: What operating system are you on?
multiple: true
options:
- Linux
- Windows
- macOS
- Other
validations:
required: true
- type: textarea
id: os-details
attributes:
label: Operating System Details
description: You can add more details about your operating system here, in particular if you chose "Other".
- type: input
id: fastapi-version
attributes:
label: FastAPI Version
description: |
What FastAPI version are you using?
You can find the FastAPI version with:
```bash
python -c "import fastapi; print(fastapi.__version__)"
```
validations:
required: true
- type: input
id: python-version
attributes:
label: Python Version
description: |
What Python version are you using?
You can find the Python version with:
```bash
python --version
```
validations:
required: true
- type: textarea
id: context
attributes:
label: Additional Context
description: Add any additional context information or screenshots you think are useful.

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

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

View File

@@ -0,0 +1,10 @@
name: "Notify Translations"
description: "Notify in the issue for a translation when there's a new PR available"
author: "Sebastián Ramírez <tiangolo@gmail.com>"
inputs:
token:
description: 'Token, to read the GitHub API. Can be passed in using {{ secrets.GITHUB_TOKEN }}'
required: true
runs:
using: 'docker'
image: 'Dockerfile'

View File

@@ -0,0 +1,104 @@
import logging
import time
from pathlib import Path
import random
from typing import Dict, Optional
import yaml
from github import Github
from pydantic import BaseModel, BaseSettings, SecretStr
awaiting_label = "awaiting review"
lang_all_label = "lang-all"
approved_label = "approved-2"
translations_path = Path(__file__).parent / "translations.yml"
class Settings(BaseSettings):
github_repository: str
input_token: SecretStr
github_event_path: Path
github_event_name: Optional[str] = None
input_debug: Optional[bool] = False
class PartialGitHubEventIssue(BaseModel):
number: int
class PartialGitHubEvent(BaseModel):
pull_request: PartialGitHubEventIssue
if __name__ == "__main__":
settings = Settings()
if settings.input_debug:
logging.basicConfig(level=logging.DEBUG)
else:
logging.basicConfig(level=logging.INFO)
logging.debug(f"Using config: {settings.json()}")
g = Github(settings.input_token.get_secret_value())
repo = g.get_repo(settings.github_repository)
if not settings.github_event_path.is_file():
raise RuntimeError(
f"No github event file available at: {settings.github_event_path}"
)
contents = settings.github_event_path.read_text()
github_event = PartialGitHubEvent.parse_raw(contents)
translations_map: Dict[str, int] = yaml.safe_load(translations_path.read_text())
logging.debug(f"Using translations map: {translations_map}")
sleep_time = random.random() * 10 # random number between 0 and 10 seconds
pr = repo.get_pull(github_event.pull_request.number)
logging.debug(
f"Processing PR: {pr.number}, with anti-race condition sleep time: {sleep_time}"
)
if pr.state == "open":
logging.debug(f"PR is open: {pr.number}")
label_strs = set([label.name for label in pr.get_labels()])
if lang_all_label in label_strs and awaiting_label in label_strs:
logging.info(
f"This PR seems to be a language translation and awaiting reviews: {pr.number}"
)
if approved_label in label_strs:
message = (
f"It seems this PR already has the approved label: {pr.number}"
)
logging.error(message)
raise RuntimeError(message)
langs = []
for label in label_strs:
if label.startswith("lang-") and not label == lang_all_label:
langs.append(label[5:])
for lang in langs:
if lang in translations_map:
num = translations_map[lang]
logging.info(
f"Found a translation issue for language: {lang} in issue: {num}"
)
issue = repo.get_issue(num)
message = f"Good news everyone! 😉 There's a new translation PR to be reviewed: #{pr.number} 🎉"
already_notified = False
time.sleep(sleep_time)
logging.info(
f"Sleeping for {sleep_time} seconds to avoid race conditions and multiple comments"
)
logging.info(
f"Checking current comments in issue: {num} to see if already notified about this PR: {pr.number}"
)
for comment in issue.get_comments():
if message in comment.body:
already_notified = True
if not already_notified:
logging.info(
f"Writing comment in issue: {num} about PR: {pr.number}"
)
issue.create_comment(message)
else:
logging.info(
f"Issue: {num} was already notified of PR: {pr.number}"
)
else:
logging.info(
f"Changing labels in a closed PR doesn't trigger comments, PR: {pr.number}"
)
logging.info("Finished")

View File

@@ -0,0 +1,16 @@
pt: 1211
es: 1218
zh: 1228
ru: 1362
it: 1556
ja: 1572
uk: 1748
tr: 1892
fr: 1972
ko: 2017
sq: 2041
pl: 3169
de: 3716
id: 3717
az: 3994
nl: 4701

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'

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

@@ -0,0 +1,538 @@
import logging
import subprocess
import sys
from collections import Counter, defaultdict
from datetime import datetime, timedelta, timezone
from pathlib import Path
from typing import Container, DefaultDict, 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):
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)
tiers: DefaultDict[float, Dict[str, SponsorEntity]] = defaultdict(dict)
for node in nodes:
tiers[node.tier.monthlyPriceInDollars][
node.sponsorEntity.login
] = node.sponsorEntity
return tiers
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,
)
tiers = get_individual_sponsors(settings=settings)
keys = list(tiers.keys())
keys.sort(reverse=True)
sponsors = []
for key in keys:
sponsor_group = []
for login, sponsor in tiers[key].items():
sponsor_group.append(
{"login": login, "avatarUrl": sponsor.avatarUrl, "url": sponsor.url}
)
sponsors.append(sponsor_group)
people = {
"maintainers": maintainers,
"experts": experts,
"last_month_active": last_month_active,
"top_contributors": top_contributors,
"top_reviewers": top_reviewers,
}
github_sponsors = {
"sponsors": sponsors,
}
people_path = Path("./docs/en/data/people.yml")
github_sponsors_path = Path("./docs/en/data/github_sponsors.yml")
people_old_content = people_path.read_text(encoding="utf-8")
github_sponsors_old_content = github_sponsors_path.read_text(encoding="utf-8")
new_people_content = yaml.dump(
people, sort_keys=False, width=200, allow_unicode=True
)
new_github_sponsors_content = yaml.dump(
github_sponsors, sort_keys=False, width=200, allow_unicode=True
)
if (
people_old_content == new_people_content
and github_sponsors_old_content == new_github_sponsors_content
):
logging.info("The FastAPI People data hasn't changed, finishing.")
sys.exit(0)
people_path.write_text(new_people_content, encoding="utf-8")
github_sponsors_path.write_text(new_github_sponsors_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), str(github_sponsors_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")

52
.github/workflows/build-docs.yml vendored Normal file
View File

@@ -0,0 +1,52 @@
name: Build Docs
on:
push:
branches:
- master
pull_request:
types: [opened, synchronize]
jobs:
build-docs:
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@v2
with:
python-version: "3.7"
- uses: actions/cache@v2
id: cache
with:
path: ${{ env.pythonLocation }}
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-docs-v2
- name: Install Flit
if: steps.cache.outputs.cache-hit != 'true'
run: python3.7 -m pip install flit
- name: Install docs extras
if: steps.cache.outputs.cache-hit != 'true'
run: python3.7 -m flit install --deps production --extras doc
- name: Install Material for MkDocs Insiders
if: github.event.pull_request.head.repo.fork == false && steps.cache.outputs.cache-hit != 'true'
run: pip install git+https://${{ secrets.ACTIONS_TOKEN }}@github.com/squidfunk/mkdocs-material-insiders.git
- name: Build Docs
run: python3.7 ./scripts/docs.py build-all
- name: Zip docs
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.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,29 +0,0 @@
name: Build and Deploy to Netlify
on:
push:
pull_request:
types: [opened, synchronize]
jobs:
build:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: "3.7"
- name: Install Flit
run: python3.7 -m pip install flit
- name: Install docs extras
run: python3.7 -m flit install --extras doc
- name: Build MkDocs
run: python3.7 -m mkdocs build
- name: Deploy to Netlify
uses: nwtgck/actions-netlify@v1.0.3
with:
publish-dir: './site'
production-branch: master
github-token: ${{ secrets.GITHUB_TOKEN }}
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}

30
.github/workflows/issue-manager.yml vendored Normal file
View File

@@ -0,0 +1,30 @@
name: Issue Manager
on:
schedule:
- cron: "0 0 * * *"
issue_comment:
types:
- created
issues:
types:
- labeled
pull_request_target:
types:
- labeled
workflow_dispatch:
jobs:
issue-manager:
runs-on: ubuntu-latest
steps:
- uses: tiangolo/issue-manager@0.4.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
config: >
{
"answered": {
"delay": 864000,
"message": "Assuming the original need was handled, this will be automatically closed now. But feel free to add more comments or create new issues or PRs."
}
}

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

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

@@ -0,0 +1,40 @@
name: Latest Changes
on:
pull_request_target:
branches:
- master
types:
- closed
workflow_dispatch:
inputs:
number:
description: PR number
required: true
debug_enabled:
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
required: false
default: false
jobs:
latest-changes:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
# To allow latest-changes to commit to master
token: ${{ secrets.ACTIONS_TOKEN }}
# Allow debugging with tmate
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}
with:
limit-access-to-actor: true
token: ${{ secrets.ACTIONS_TOKEN }}
standard_token: ${{ secrets.GITHUB_TOKEN }}
- uses: 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

View File

@@ -1,19 +0,0 @@
on:
schedule:
- cron: "0 0 * * *"
jobs:
issue-manager:
runs-on: ubuntu-latest
steps:
- uses: tiangolo/issue-manager@master
with:
token: ${{ secrets.GITHUB_TOKEN }}
config: >
{
"answered": {
"users": ["tiangolo", "dmontagu"],
"delay": 864000,
"message": "Assuming the original issue was solved, it will be automatically closed now. But feel free to add more comments or create new issues."
}
}

View File

@@ -0,0 +1,21 @@
name: Notify Translations
on:
pull_request_target:
types:
- labeled
jobs:
notify-translations:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# Allow debugging with tmate
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}
with:
limit-access-to-actor: true
- uses: ./.github/actions/notify-translations
with:
token: ${{ secrets.GITHUB_TOKEN }}

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

@@ -0,0 +1,29 @@
name: FastAPI People
on:
schedule:
- cron: "0 14 1 * *"
workflow_dispatch:
inputs:
debug_enabled:
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
required: false
default: false
jobs:
fastapi-people:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# Allow debugging with tmate
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}
with:
limit-access-to-actor: true
token: ${{ secrets.ACTIONS_TOKEN }}
standard_token: ${{ secrets.GITHUB_TOKEN }}
- uses: ./.github/actions/people
with:
token: ${{ secrets.ACTIONS_TOKEN }}
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:
preview-docs:
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 }}"

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

@@ -0,0 +1,46 @@
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@v2
with:
python-version: "3.6"
- uses: actions/cache@v2
id: cache
with:
path: ${{ env.pythonLocation }}
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-publish
- name: Install Flit
if: steps.cache.outputs.cache-hit != 'true'
run: pip install flit
- name: Install Dependencies
if: steps.cache.outputs.cache-hit != 'true'
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

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

@@ -0,0 +1,41 @@
name: Test
on:
push:
branches:
- master
pull_request:
types: [opened, synchronize]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"]
fail-fast: false
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- uses: actions/cache@v2
id: cache
with:
path: ${{ env.pythonLocation }}
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-test-v02
- name: Install Flit
if: steps.cache.outputs.cache-hit != 'true'
run: pip install flit
- name: Install Dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: flit install --symlink
- name: Lint
if: ${{ matrix.python-version != '3.6' }}
run: bash scripts/lint.sh
- name: Test
run: bash scripts/test.sh
- name: Upload coverage
uses: codecov/codecov-action@v2

9
.gitignore vendored
View File

@@ -14,3 +14,12 @@ test.db
log.txt
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"

137
README.md
View File

@@ -5,17 +5,17 @@
<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+event%3Apush+branch%3Amaster" target="_blank">
<img src="https://github.com/tiangolo/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
</a>
<a href="https://codecov.io/gh/tiangolo/fastapi" target="_blank">
<img src="https://codecov.io/gh/tiangolo/fastapi/branch/master/graph/badge.svg" 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">
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://img.shields.io/pypi/pyversions/fastapi.svg?color=%2334D058" alt="Supported Python versions">
</a>
</p>
@@ -33,49 +33,81 @@ 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>
## Sponsors
<!-- sponsors -->
<a href="https://bit.ly/2QSouzH" target="_blank" title="Jina: build neural search-as-a-service for any kind of data in just minutes."><img src="https://fastapi.tiangolo.com/img/sponsors/jina.svg"></a>
<a href="https://cryptapi.io/" target="_blank" title="CryptAPI: Your easy to use, secure and privacy oriented payment gateway."><img src="https://fastapi.tiangolo.com/img/sponsors/cryptapi.svg"></a>
<a href="https://classiq.link/n4s" target="_blank" title="Join the team building a new SaaS platform that will change the computing world"><img src="https://fastapi.tiangolo.com/img/sponsors/classiq.png"></a>
<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>
<a href="https://www.investsuite.com/jobs" target="_blank" title="Wealthtech jobs with FastAPI"><img src="https://fastapi.tiangolo.com/img/sponsors/investsuite.svg"></a>
<a href="https://talkpython.fm/fastapi-sponsor" target="_blank" title="FastAPI video courses on demand from people you trust"><img src="https://fastapi.tiangolo.com/img/sponsors/talkpython.png"></a>
<a href="https://testdriven.io/courses/tdd-fastapi/" target="_blank" title="Learn to build high-quality web apps with best practices"><img src="https://fastapi.tiangolo.com/img/sponsors/testdriven.svg"></a>
<a href="https://github.com/deepset-ai/haystack/" target="_blank" title="Build powerful search from composable, open source building blocks"><img src="https://fastapi.tiangolo.com/img/sponsors/haystack-fastapi.svg"></a>
<a href="https://www.udemy.com/course/fastapi-rest/" target="_blank" title="Learn FastAPI by building a complete project. Extend your knowledge on advanced web development-AWS, Payments, Emails."><img src="https://fastapi.tiangolo.com/img/sponsors/ines-course.jpg"></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]*"
## **Typer**, the FastAPI of CLIs
<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>
<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>
---
If you are building a <abbr title="Command Line Interface">CLI</abbr> app to be used in the terminal instead of a web API, check out <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>.
**Typer** is FastAPI's little sibling. And it's intended to be the **FastAPI of CLIs**. ⌨️ 🚀
## Requirements
@@ -88,16 +120,28 @@ FastAPI stands on the shoulders of giants:
## Installation
```bash
pip install fastapi
<div class="termy">
```console
$ pip install fastapi
---> 100%
```
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>.
</div>
```bash
pip install uvicorn
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">
```console
$ pip install "uvicorn[standard]"
---> 100%
```
</div>
## Example
### Create it
@@ -105,6 +149,8 @@ pip install uvicorn
* Create a file `main.py` with:
```Python
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@@ -116,7 +162,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}
```
@@ -125,7 +171,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()
@@ -137,7 +185,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}
```
@@ -151,10 +199,20 @@ If you don't know, check the _"In a hurry?"_ section about <a href="https://fast
Run the server with:
```bash
uvicorn main:app --reload
<div class="termy">
```console
$ uvicorn main:app --reload
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [28720]
INFO: Started server process [28722]
INFO: Waiting for application startup.
INFO: Application startup complete.
```
</div>
<details markdown="1">
<summary>About the command <code>uvicorn main:app --reload</code>...</summary>
@@ -205,7 +263,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
@@ -215,7 +275,7 @@ app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: bool = None
is_offer: Optional[bool] = None
@app.get("/")
@@ -224,7 +284,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}
@@ -261,7 +321,7 @@ And now, go to <a href="http://127.0.0.1:8000/redoc" class="external-link" targe
### Recap
In summary, you declare **once** the types of parameters, body, etc. as function parameters.
In summary, you declare **once** the types of parameters, body, etc. as function parameters.
You do that with standard modern Python types.
@@ -318,7 +378,7 @@ Coming back to the previous code example, **FastAPI** will:
* As the `q` parameter is declared with `= None`, it is optional.
* Without the `None` it would be required (as is the body in the case with `PUT`).
* For `PUT` requests to `/items/{item_id}`, Read the body as JSON:
* Check that it has a required attribute `name` that should be a `str`.
* Check that it has a required attribute `name` that should be a `str`.
* Check that it has a required attribute `price` that has to be a `float`.
* Check that it has an optional attribute `is_offer`, that should be a `bool`, if present.
* All this would also work for deeply nested JSON objects.
@@ -363,9 +423,9 @@ For a more complete example including more features, see the <a href="https://fa
* A very powerful and easy to use **<abbr title="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** system.
* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth.
* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic).
* **GraphQL** integration with <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> and other libraries.
* Many extra features (thanks to Starlette) as:
* **WebSockets**
* **GraphQL**
* extremely easy tests based on `requests` and `pytest`
* **CORS**
* **Cookie Sessions**
@@ -386,20 +446,19 @@ 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://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://requests.readthedocs.io" target="_blank"><code>requests</code></a> - Required if you want to use the `TestClient`.
* <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).
* <a href="https://graphene-python.org/" target="_blank"><code>graphene</code></a> - Required for `GraphQLApp` support.
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Required if you want to use `UJSONResponse`.
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]`.
You can install all of these with `pip install "fastapi[all]"`.
## License

31
SECURITY.md Normal file
View File

@@ -0,0 +1,31 @@
# Security Policy
Security is very important for FastAPI and its community. 🔒
Learn more about it below. 👇
## Versions
The latest versions of FastAPI are supported.
You are encouraged to [write tests](https://fastapi.tiangolo.com/tutorial/testing/) for your application and update your FastAPI version frequently after ensuring that your tests are passing. This way you will benefit from the latest features, bug fixes, and **security fixes**.
You can learn more about [FastAPI versions and how to pin and upgrade them](https://fastapi.tiangolo.com/deployment/versions/) for your project in the docs.
## Reporting a Vulnerability
If you think you found a vulnerability, and even if you are not sure about it, please report it right away by sending an email to: security@tiangolo.com. Please try to be as explicit as possible, describing all the steps and example code to reproduce the security issue.
I (the author, [@tiangolo](https://twitter.com/tiangolo)) will review it thoroughly and get back to you.
## Public Discussions
Please restrain from publicly discussing a potential security vulnerability. 🙊
It's better to discuss privately and try to find a solution first, to limit the potential impact as much as possible.
---
Thanks for your help!
The FastAPI community and I thank you for that. 🙇

View File

@@ -1,102 +0,0 @@
!!! warning
This is a rather advanced topic.
If you are starting with **FastAPI**, you might not need this.
By default, **FastAPI** will return the responses using Starlette's `JSONResponse`.
You can override it by returning a `Response` directly as seen in [Return a Response directly](response-directly.md){.internal-link target=_blank}.
But if you return a `Response` directly, the data won't be automatically converted, and the documentation won't be automatically generated (for example, including the specific "media type", in the HTTP header `Content-Type`).
But you can also declare the `Response` that you want to be used, in the *path operation decorator*.
The contents that you return from your *path operation function* will be put inside of that `Response`.
And if that `Response` has a JSON media type (`application/json`), like is the case with the `JSONResponse` and `UJSONResponse`, the data you return will be automatically converted (and filtered) with any Pydantic `response_model` that you declared in the *path operation decorator*.
!!! note
If you use a response class with no media type, FastAPI will expect your response to have no content, so it will not document the response format in its generated OpenAPI docs.
## Use `UJSONResponse`
For example, if you are squeezing performance, you can install and use `ujson` and set the response to be Starlette's `UJSONResponse`.
Import the `Response` class (sub-class) you want to use and declare it in the *path operation decorator*.
```Python hl_lines="2 7"
{!./src/custom_response/tutorial001.py!}
```
!!! note
Notice that you import it directly from `starlette.responses`, not from `fastapi`.
!!! info
The parameter `response_class` will also be used to define the "media type" of the response.
In this case, the HTTP header `Content-Type` will be set to `application/json`.
And it will be documented as such in OpenAPI.
## HTML Response
To return a response with HTML directly from **FastAPI**, use `HTMLResponse`.
* Import `HTMLResponse`.
* Pass `HTMLResponse` as the parameter `content_type` of your *path operation*.
```Python hl_lines="2 7"
{!./src/custom_response/tutorial002.py!}
```
!!! note
Notice that you import it directly from `starlette.responses`, not from `fastapi`.
!!! info
The parameter `response_class` will also be used to define the "media type" of the response.
In this case, the HTTP header `Content-Type` will be set to `text/html`.
And it will be documented as such in OpenAPI.
### Return a Starlette `Response`
As seen in [Return a Response directly](response-directly.md){.internal-link target=_blank}, you can also override the response directly in your *path operation*, by returning it.
The same example from above, returning an `HTMLResponse`, could look like:
```Python hl_lines="2 7 19"
{!./src/custom_response/tutorial003.py!}
```
!!! warning
A `Response` returned directly by your *path operation function* won't be documented in OpenAPI (for example, the `Content-Type` won't be documented) and won't be visible in the automatic interactive docs.
!!! info
Of course, the actual `Content-Type` header, status code, etc, will come from the `Response` object your returned.
### Document in OpenAPI and override `Response`
If you want to override the response from inside of the function but at the same time document the "media type" in OpenAPI, you can use the `response_class` parameter AND return a `Response` object.
The `response_class` will then be used only to document the OpenAPI *path operation*, but your `Response` will be used as is.
#### Return an `HTMLResponse` directly
For example, it could be something like:
```Python hl_lines="7 23 21"
{!./src/custom_response/tutorial004.py!}
```
In this example, the function `generate_html_response()` already generates a Starlette `Response` instead of the HTML in a `str`.
By returning the result of calling `generate_html_response()`, you are already returning a `Response` that will override the default **FastAPI** behavior.
But as you passed the `HTMLResponse` in the `response_class`, **FastAPI** will know how to document it in OpenAPI and the interactive docs as HTML with `text/html`:
<img src="/img/tutorial/custom-response/image01.png">
## 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

@@ -1,43 +0,0 @@
**FastAPI** has optional support for GraphQL (provided by Starlette directly), using the `graphene` library.
You can combine normal FastAPI *path operations* with GraphQL on the same application.
## Import and use `graphene`
GraphQL is implemented with Graphene, you can check <a href="https://docs.graphene-python.org/en/latest/quickstart/" class="external-link" target="_blank">Graphene's docs</a> for more details.
Import `graphene` and define your GraphQL data:
```Python hl_lines="1 6 7 8 9 10"
{!./src/graphql/tutorial001.py!}
```
## Add Starlette's `GraphQLApp`
Then import and add Starlette's `GraphQLApp`:
```Python hl_lines="3 14"
{!./src/graphql/tutorial001.py!}
```
!!! info
Here we are using `.add_route`, that is the way to add a route in Starlette (inherited by FastAPI) without declaring the specific operation (as would be with `.get()`, `.post()`, etc).
## Check it
Run it with Uvicorn and open your browser at <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>.
You will see GraphiQL web user interface:
<img src="/img/tutorial/graphql/image01.png">
## More details
For more details, including:
* Accessing request information
* Adding background tasks
* Using normal or async functions
check the official <a href="https://www.starlette.io/graphql/" class="external-link" target="_blank">Starlette GraphQL docs</a>.

View File

@@ -1,50 +0,0 @@
## OpenAPI operationId
!!! warning
If you are not an "expert" in OpenAPI, you probably don't need this.
You can set the OpenAPI `operationId` to be used in your *path operation* with the parameter `operation_id`.
You would have to make sure that it is unique for each operation.
```Python hl_lines="6"
{!./src/path_operation_advanced_configuration/tutorial001.py!}
```
### Using the *path operation function* name as the operationId
If you want to use your APIs' function names as `operationId`s, you can iterate over all of them and override each *path operation's* `operation_id` using their `APIRoute.name`.
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"
{!./src/path_operation_advanced_configuration/tutorial002.py!}
```
!!! tip
If you manually call `app.openapi()`, you should update the `operationId`s before that.
!!! warning
If you do this, you have to make sure each one of your *path operation functions* has a unique name.
Even if they are in different modules (Python files).
## Exclude from OpenAPI
To exclude a *path operation* from the generated OpenAPI schema (and thus, from the automatic documentation systems), use the parameter `include_in_schema` and set it to `False`;
```Python hl_lines="6"
{!./src/path_operation_advanced_configuration/tutorial003.py!}
```
## Advanced description from docstring
You can limit the lines used from the docstring of a *path operation function* for OpenAPI.
Adding an `\f` (an escaped "form feed" character) causes **FastAPI** to truncate the output used for OpenAPI at this point.
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"
{!./src/path_operation_advanced_configuration/tutorial004.py!}
```

View File

@@ -1,92 +0,0 @@
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"
{!./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"
{!./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"
{!./src/sub_applications/tutorial001.py!}
```
## Check the automatic API docs
Now, run `uvicorn`, if your file is at `main.py`, it would be:
```bash
uvicorn main:app --reload
```
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

@@ -1,9 +0,0 @@
## Testing WebSockets
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"
{!./src/app_testing/tutorial002.py!}
```

135
docs/az/mkdocs.yml Normal file
View File

@@ -0,0 +1,135 @@
site_name: FastAPI
site_description: FastAPI framework, high performance, easy to learn, fast to code, ready for production
site_url: https://fastapi.tiangolo.com/az/
theme:
name: material
custom_dir: overrides
palette:
- scheme: default
primary: teal
accent: amber
toggle:
icon: material/lightbulb
name: Switch to light mode
- scheme: slate
primary: teal
accent: amber
toggle:
icon: material/lightbulb-outline
name: Switch to dark mode
features:
- search.suggest
- search.highlight
- content.tabs.link
icon:
repo: fontawesome/brands/github-alt
logo: https://fastapi.tiangolo.com/img/icon-white.svg
favicon: https://fastapi.tiangolo.com/img/favicon.png
language: en
repo_name: tiangolo/fastapi
repo_url: https://github.com/tiangolo/fastapi
edit_uri: ''
plugins:
- search
- markdownextradata:
data: data
nav:
- FastAPI: index.md
- Languages:
- en: /
- az: /az/
- de: /de/
- es: /es/
- fa: /fa/
- fr: /fr/
- id: /id/
- it: /it/
- ja: /ja/
- ko: /ko/
- nl: /nl/
- pl: /pl/
- pt: /pt/
- ru: /ru/
- sq: /sq/
- tr: /tr/
- uk: /uk/
- zh: /zh/
markdown_extensions:
- toc:
permalink: true
- markdown.extensions.codehilite:
guess_lang: false
- mdx_include:
base_path: docs
- admonition
- codehilite
- extra
- pymdownx.superfences:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed:
alternate_style: true
extra:
analytics:
provider: google
property: UA-133183413-1
social:
- icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi
- icon: fontawesome/brands/discord
link: https://discord.gg/VQjSZaeJmf
- icon: fontawesome/brands/twitter
link: https://twitter.com/fastapi
- icon: fontawesome/brands/linkedin
link: https://www.linkedin.com/in/tiangolo
- icon: fontawesome/brands/dev
link: https://dev.to/tiangolo
- icon: fontawesome/brands/medium
link: https://medium.com/@tiangolo
- icon: fontawesome/solid/globe
link: https://tiangolo.com
alternate:
- link: /
name: en - English
- link: /az/
name: az
- link: /de/
name: de
- link: /es/
name: es - español
- link: /fa/
name: fa
- link: /fr/
name: fr - français
- link: /id/
name: id
- link: /it/
name: it - italiano
- link: /ja/
name: ja - 日本語
- link: /ko/
name: ko - 한국어
- link: /nl/
name: nl
- link: /pl/
name: pl
- link: /pt/
name: pt - português
- link: /ru/
name: ru - русский язык
- link: /sq/
name: sq - shqip
- link: /tr/
name: tr - Türkçe
- link: /uk/
name: uk - українська мова
- link: /zh/
name: zh - 汉语
extra_css:
- https://fastapi.tiangolo.com/css/termynal.css
- https://fastapi.tiangolo.com/css/custom.css
extra_javascript:
- https://fastapi.tiangolo.com/js/termynal.js
- https://fastapi.tiangolo.com/js/custom.js

View File

@@ -1,175 +0,0 @@
First, you might want to see the basic ways to [help FastAPI and get help](help-fastapi.md){.internal-link target=_blank}.
## Developing
If you already cloned the repository and you know that you need to deep dive in the code, here are some guidelines to set up your environment.
### Virtual environment with `venv`
You can create a virtual environment in a directory using Python's `venv` module:
```console
$ python -m venv env
```
That will create a directory `./env/` with the Python binaries and then you will be able to install packages for that isolated environment.
### Activate the environment
Activate the new environment with:
```console
$ source ./env/bin/activate
```
Or in Windows' PowerShell:
```console
$ .\env\Scripts\Activate.ps1
```
Or if you use Bash for Windows (e.g. <a href="https://gitforwindows.org/" class="external-link" target="_blank">Git Bash</a>):
```console
$ source ./env/Scripts/activate
```
To check it worked, use:
```console
$ which pip
some/directory/fastapi/env/bin/pip
```
If it shows the `pip` binary at `env/bin/pip` then it worked. 🎉
Or in Windows PowerShell:
```console
$ Get-Command pip
some/directory/fastapi/env/bin/pip
```
!!! tip
Every time you install a new package with `pip` under that environment, activate the environment again.
This makes sure that if you use a terminal program installed by that package (like `flit`), you use the one from your local environment and not any other that could be installed globally.
### Flit
**FastAPI** uses <a href="https://flit.readthedocs.io/en/latest/index.html" class="external-link" target="_blank">Flit</a> to build, package and publish the project.
After activating the environment as described above, install `flit`:
```console
$ pip install flit
```
Now re-activate the environment to make sure you are using the `flit` you just installed (and not a global one).
And now use `flit` to install the development dependencies:
```console
$ flit install --deps develop --symlink
```
It will install all the dependencies and your local FastAPI in your local environment.
#### Using your local FastAPI
If you create a Python file that imports and uses FastAPI, and run it with the Python from your local environment, it will use your local FastAPI source code.
And if you update that local FastAPI source code, as it is installed with `--symlink`, when you run that Python file again, it will use the fresh version of FastAPI you just edited.
That way, you don't have to "install" your local version to be able to test every change.
### Format
There is a script that you can run that will format and clean all your code:
```console
$ bash scripts/format.sh
```
It will also auto-sort all your imports.
For it to sort them correctly, you need to have FastAPI installed locally in your environment, with the command in the section above:
```console
$ flit install --symlink
```
### Format imports
There is another script that formats all the imports and makes sure you don't have unused imports:
```console
$ bash scripts/format-imports.sh
```
As it runs one command after the other and modifies and reverts many files, it takes a bit longer to run, so it might be easier to use `scripts/format.sh` frequently and `scripts/format-imports.sh` only before committing.
## Docs
The documentation uses <a href="https://www.mkdocs.org/" class="external-link" target="_blank">MkDocs</a>.
All the documentation is in Markdown format in the directory `./docs`.
Many of the tutorials have blocks of code.
In most of the cases, these blocks of code are actual complete applications that can be run as is.
In fact, those blocks of code are not written inside the Markdown, they are Python files in the `./docs/src/` directory.
And those Python files are included/injected in the documentation when generating the site.
### Docs for tests
Most of the tests actually run against the example source files in the documentation.
This helps making sure that:
* The documentation is up to date.
* The documentation examples can be run as is.
* Most of the features are covered by the documentation, ensured by test coverage.
During local development, there is a script that builds the site and checks for any changes, live-reloading:
```console
$ bash scripts/docs-live.sh
```
It will serve the documentation on `http://0.0.0.0:8008`.
That way, you can edit the documentation/source files and see the changes live.
### Apps and docs at the same time
If you run the examples with, e.g.:
```console
$ uvicorn tutorial001:app --reload
```
as Uvicorn by default will use the port `8000`, the documentation on port `8008` won't clash.
## Tests
There is a script that you can run locally to test all the code and generate coverage reports in HTML:
```console
$ bash scripts/test-cov-html.sh
```
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 +0,0 @@
a.external-link::after {
/* \00A0 is a non-breaking space
to make the mark be on the same line as the link
*/
content: "\00A0[↪]";
}
a.internal-link::after {
/* \00A0 is a non-breaking space
to make the mark be on the same line as the link
*/
content: "\00A0↪";
}

203
docs/de/docs/features.md Normal file
View File

@@ -0,0 +1,203 @@
# Merkmale
## FastAPI Merkmale
**FastAPI** ermöglicht Ihnen folgendes:
### Basiert auf offenen Standards
* <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a> für API-Erstellung, zusammen mit Deklarationen von <abbr title="auch genannt: Endpunkte, Routen">Pfad</abbr> <abbr title="gemeint sind: HTTP-Methoden, wie POST, GET, PUT, DELETE">Operationen</abbr>, Parameter, Nachrichtenrumpf-Anfragen (englisch: body request), Sicherheit, etc.
* Automatische Dokumentation der Datenentitäten mit dem <a href="https://json-schema.org/" class="external-link" target="_blank"><strong>JSON Schema</strong></a> (OpenAPI basiert selber auf dem JSON Schema).
* Entworfen auf Grundlage dieser Standards nach einer sorgfältigen Studie, statt einer nachträglichen Schicht über diesen Standards.
* Dies ermöglicht automatische **Quellcode-Generierung auf Benutzerebene** in vielen Sprachen.
### Automatische Dokumentation
Mit einer interaktiven API-Dokumentation und explorativen webbasierten Benutzerschnittstellen. Da FastAPI auf OpenAPI basiert, gibt es hierzu mehrere Optionen, wobei zwei standartmäßig vorhanden sind.
* <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank"><strong>Swagger UI</strong></a>, bietet interaktive Exploration: testen und rufen Sie ihre API direkt vom Webbrowser auf.
![Swagger UI Interaktion](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png)
* Alternative API-Dokumentation mit <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank"><strong>ReDoc</strong></a>.
![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png)
### Nur modernes Python
Alles basiert auf **Python 3.6 Typ**-Deklarationen (dank Pydantic). Es muss keine neue Syntax gelernt werden, nur standardisiertes modernes Python.
Wenn Sie eine kurze, zweiminütige, Auffrischung in der Benutzung von Python Typ-Deklarationen benötigen (auch wenn Sie FastAPI nicht nutzen), schauen Sie sich diese kurze Einführung an (Englisch): Python Types{.internal-link target=_blank}.
Sie schreiben Standard-Python mit Typ-Deklarationen:
```Python
from typing import List, Dict
from datetime import date
from pydantic import BaseModel
# Deklariere eine Variable als str
# und bekomme Editor-Unterstütung innerhalb der Funktion
def main(user_id: str):
return user_id
# Ein Pydantic model
class User(BaseModel):
id: int
name: str
joined: date
```
Dies kann nun wiefolgt benutzt werden:
```Python
my_user: User = User(id=3, name="John Doe", joined="2018-07-19")
second_user_data = {
"id": 4,
"name": "Mary",
"joined": "2018-11-30",
}
my_second_user: User = User(**second_user_data)
```
!!! info
`**second_user_data` bedeutet:
Übergebe die Schlüssel und die zugehörigen Werte des `second_user_data` Datenwörterbuches direkt als Schlüssel-Wert Argumente, äquivalent zu: `User(id=4, name="Mary", joined="2018-11-30")`
### Editor Unterstützung
FastAPI wurde so entworfen, dass es einfach und intuitiv zu benutzen ist; alle Entscheidungen wurden auf mehreren Editoren getestet (sogar vor der eigentlichen Implementierung), um so eine best mögliche Entwicklererfahrung zu gewährleisten.
In der letzen Python Entwickler Umfrage stellte sich heraus, dass <a href="https://www.jetbrains.com/research/python-developers-survey-2017/#tools-and-features" class="external-link" target="_blank">die meist genutzte Funktion die "Autovervollständigung" ist</a>.
Die gesamte Struktur von **FastAPI** soll dem gerecht werden. Autovervollständigung funktioniert überall.
Sie müssen selten in die Dokumentation schauen.
So kann ihr Editor Sie unterstützen:
* in <a href="https://code.visualstudio.com/" class="external-link" target="_blank">Visual Studio Code</a>:
![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png)
* in <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a>:
![editor support](https://fastapi.tiangolo.com/img/pycharm-completion.png)
Sie bekommen Autovervollständigung an Stellen, an denen Sie dies vorher nicht für möglich gehalten hätten. Zum Beispiel der `price` Schlüssel aus einem JSON Datensatz (dieser könnte auch verschachtelt sein) aus einer Anfrage.
Hierdurch werden Sie nie wieder einen falschen Schlüsselnamen benutzen und sparen sich lästiges Suchen in der Dokumentation, um beispielsweise herauszufinden ob Sie `username` oder `user_name` als Schlüssel verwenden.
### Kompakt
FastAPI nutzt für alles sensible **Standard-Einstellungen**, welche optional überall konfiguriert werden können. Alle Parameter können ganz genau an Ihre Bedürfnisse angepasst werden, sodass sie genau die API definieren können, die sie brachen.
Aber standartmäßig, **"funktioniert einfach"** alles.
### Validierung
* Validierung für die meisten (oder alle?) Python **Datentypen**, hierzu gehören:
* JSON Objekte (`dict`).
* JSON Listen (`list`), die den Typ ihrer Elemente definieren.
* Zeichenketten (`str`), mit definierter minimaler und maximaler Länge.
* Zahlen (`int`, `float`) mit minimaler und maximaler Größe, usw.
* Validierung für ungewögnliche Typen, wie:
* URL.
* Email.
* UUID.
* ... und andere.
Die gesamte Validierung übernimmt das etablierte und robuste **Pydantic**.
### Sicherheit und Authentifizierung
Sicherheit und Authentifizierung integriert. Ohne einen Kompromiss aufgrund einer Datenbank oder den Datenentitäten.
Unterstützt alle von OpenAPI definierten Sicherheitsschemata, hierzu gehören:
* HTTP Basis Authentifizierung.
* **OAuth2** (auch mit **JWT Zugriffstokens**). Schauen Sie sich hierzu dieses Tutorial an: [OAuth2 mit JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank}.
* API Schlüssel in:
* Kopfzeile (HTTP Header).
* Anfrageparametern.
* Cookies, etc.
Zusätzlich gibt es alle Sicherheitsfunktionen von Starlette (auch **session cookies**).
Alles wurde als wiederverwendbare Werkzeuge und Komponenten geschaffen, die einfach in ihre Systeme, Datenablagen, relationale und nicht-relationale Datenbanken, ..., integriert werden können.
### Einbringen von Abhängigkeiten (meist: Dependency Injection)
FastAPI enthält ein extrem einfaches, aber extrem mächtiges <abbr title='oft verwendet im Zusammenhang von: Komponenten, Resourcen, Diensten, Dienstanbieter'><strong>Dependency Injection</strong></abbr> System.
* Selbst Abhängigkeiten können Abhängigkeiten haben, woraus eine Hierachie oder ein **"Graph" von Abhängigkeiten** entsteht.
* **Automatische Umsetzung** durch FastAPI.
* Alle abhängigen Komponenten könnten Daten von Anfragen, **Erweiterungen der Pfadoperations-**Einschränkungen und der automatisierten Dokumentation benötigen.
* **Automatische Validierung** selbst für *Pfadoperationen*-Parameter, die in den Abhängigkeiten definiert wurden.
* Unterstütz komplexe Benutzerauthentifizierungssysteme, mit **Datenbankverbindungen**, usw.
* **Keine Kompromisse** bei Datenbanken, Eingabemasken, usw. Sondern einfache Integration von allen.
### Unbegrenzte Erweiterungen
Oder mit anderen Worten, sie werden nicht benötigt. Importieren und nutzen Sie Quellcode nach Bedarf.
Jede Integration wurde so entworfen, dass sie einfach zu nutzen ist (mit Abhängigkeiten), sodass Sie eine Erweiterung für Ihre Anwendung mit nur zwei Zeilen an Quellcode implementieren können. Hierbei nutzen Sie die selbe Struktur und Syntax, wie bei Pfadoperationen.
### Getestet
* 100% <abbr title="Die Anzahl an Code, die automatisch getestet wird">Testabdeckung</abbr>.
* 100% <abbr title="Python Typ Annotationen, mit dennen Ihr Editor und andere exteren Werkezuge Sie besser unterstützen können">Typen annotiert</abbr>.
* Verwendet in Produktionsanwendungen.
## Starlette's Merkmale
**FastAPI** ist vollkommen kompatibel (und basiert auf) <a href="https://www.starlette.io/" class="external-link" target="_blank"><strong>Starlette</strong></a>. Das bedeutet, auch ihr eigner Starlett Quellcode funktioniert.
`FastAPI` ist eigentlich eine Unterklasse von `Starlette`. Wenn sie also bereits Starlette kennen oder benutzen, können Sie das meiste Ihres Wissen direkt anwenden.
Mit **FastAPI** bekommen Sie viele von **Starlette**'s Funktionen (da FastAPI nur Starlette auf Steroiden ist):
* Stark beeindruckende Performanz. Es ist <a href="https://github.com/encode/starlette#performance" class="external-link" target="_blank">eines der schnellsten Python frameworks, auf Augenhöhe mit **NodeJS** und **Go**</a>.
* **WebSocket**-Unterstützung.
* Hintergrundaufgaben im selben Prozess.
* Ereignisse für das Starten und Herunterfahren.
* Testclient basierend auf `requests`.
* **CORS**, GZip, statische Dateien, Antwortfluss.
* **Sitzungs und Cookie** Unterstützung.
* 100% Testabdeckung.
* 100% Typen annotiert.
## Pydantic's Merkmale
**FastAPI** ist vollkommen kompatibel (und basiert auf) <a href="https://pydantic-docs.helpmanual.io" class="external-link" target="_blank"><strong>Pydantic</strong></a>. Das bedeutet, auch jeder zusätzliche Pydantic Quellcode funktioniert.
Verfügbar sind ebenso externe auf Pydantic basierende Bibliotheken, wie <abbr title="Object-Relational Mapper (Abbildung von Objekten auf relationale Strukturen)">ORM</abbr>s, <abbr title="Object-Document Mapper (Abbildung von Objekten auf nicht-relationale Strukturen)">ODM</abbr>s für Datenbanken.
Daher können Sie in vielen Fällen das Objekt einer Anfrage **direkt zur Datenbank** schicken, weil alles automatisch validiert wird.
Das selbe gilt auch für die andere Richtung: Sie können jedes Objekt aus der Datenbank **direkt zum Klienten** schicken.
Mit **FastAPI** bekommen Sie alle Funktionen von **Pydantic** (da FastAPI für die gesamte Datenverarbeitung Pydantic nutzt):
* **Kein Kopfzerbrechen**:
* Sie müssen keine neue Schemadefinitionssprache lernen.
* Wenn Sie mit Python's Typisierung arbeiten können, können Sie auch mit Pydantic arbeiten.
* Gutes Zusammenspiel mit Ihrer/Ihrem **<abbr title="Integrierten Entwicklungsumgebung, ähnlich zu (Quellcode-)Editor">IDE</abbr>/<abbr title="Ein Programm, was Fehler im Quellcode sucht">linter</abbr>/Gehirn**:
* Weil Datenstrukturen von Pydantic einfach nur Instanzen ihrer definierten Klassen sind, sollten Autovervollständigung, Linting, mypy und ihre Intuition einwandfrei funktionieren.
* **Schnell**:
* In <a href="https://pydantic-docs.helpmanual.io/#benchmarks-tag" class="external-link" target="_blank">Vergleichen</a> ist Pydantic schneller als jede andere getestete Bibliothek.
* Validierung von **komplexen Strukturen**:
* Benutzung von hierachischen Pydantic Schemata, Python `typing`s `List` und `Dict`, etc.
* Validierungen erlauben klare und einfache Datenschemadefinition, überprüft und dokumentiert als JSON Schema.
* Sie können stark **verschachtelte JSON** Objekte haben und diese sind trotzdem validiert und annotiert.
* **Erweiterbar**:
* Pydantic erlaubt die Definition von eigenen Datentypen oder sie können die Validierung mit einer `validator` dekorierten Methode erweitern..
* 100% Testabdeckung.

465
docs/de/docs/index.md Normal file
View File

@@ -0,0 +1,465 @@
{!../../../docs/missing-translation.md!}
<p align="center">
<a href="https://fastapi.tiangolo.com"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" alt="FastAPI"></a>
</p>
<p align="center">
<em>FastAPI framework, high performance, easy to learn, fast to code, ready for production</em>
</p>
<p align="center">
<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?color=%2334D058" alt="Coverage">
</a>
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Package version">
</a>
</p>
---
**Documentation**: <a href="https://fastapi.tiangolo.com" target="_blank">https://fastapi.tiangolo.com</a>
**Source Code**: <a href="https://github.com/tiangolo/fastapi" target="_blank">https://github.com/tiangolo/fastapi</a>
---
FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.6+ based on standard Python type hints.
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%. *
* **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="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>
## Sponsors
<!-- sponsors -->
{% if sponsors %}
{% for sponsor in sponsors.gold -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor -%}
{%- for sponsor in sponsors.silver -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></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._"
<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>
---
"_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._"
<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 [...]_"
"_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>
---
## **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>
If you are building a <abbr title="Command Line Interface">CLI</abbr> app to be used in the terminal instead of a web API, check out <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>.
**Typer** is FastAPI's little sibling. And it's intended to be the **FastAPI of CLIs**. ⌨️ 🚀
## Requirements
Python 3.6+
FastAPI stands on the shoulders of giants:
* <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> for the web parts.
* <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> for the data parts.
## Installation
<div class="termy">
```console
$ pip install fastapi
---> 100%
```
</div>
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">
```console
$ pip install uvicorn[standard]
---> 100%
```
</div>
## Example
### Create it
* Create a file `main.py` 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}
```
<details markdown="1">
<summary>Or use <code>async def</code>...</summary>
If your code uses `async` / `await`, use `async def`:
```Python hl_lines="9 14"
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "q": q}
```
**Note**:
If you don't know, check the _"In a hurry?"_ section about <a href="https://fastapi.tiangolo.com/async/#in-a-hurry" target="_blank">`async` and `await` in the docs</a>.
</details>
### Run it
Run the server with:
<div class="termy">
```console
$ uvicorn main:app --reload
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [28720]
INFO: Started server process [28722]
INFO: Waiting for application startup.
INFO: Application startup complete.
```
</div>
<details markdown="1">
<summary>About the command <code>uvicorn main:app --reload</code>...</summary>
The command `uvicorn main:app` refers to:
* `main`: the file `main.py` (the Python "module").
* `app`: the object created inside of `main.py` with the line `app = FastAPI()`.
* `--reload`: make the server restart after code changes. Only do this for development.
</details>
### Check it
Open your browser at <a href="http://127.0.0.1:8000/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1:8000/items/5?q=somequery</a>.
You will see the JSON response as:
```JSON
{"item_id": 5, "q": "somequery"}
```
You already created an API that:
* Receives HTTP requests in the _paths_ `/` and `/items/{item_id}`.
* Both _paths_ take `GET` <em>operations</em> (also known as HTTP _methods_).
* The _path_ `/items/{item_id}` has a _path parameter_ `item_id` that should be an `int`.
* The _path_ `/items/{item_id}` has an optional `str` _query parameter_ `q`.
### Interactive API docs
Now go to <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 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 now, go to <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
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)
## Example upgrade
Now modify the file `main.py` to receive a body from a `PUT` request.
Declare the body using standard Python types, thanks to Pydantic.
```Python hl_lines="4 9-12 25-27"
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: Optional[bool] = None
@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}
@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
return {"item_name": item.name, "item_id": item_id}
```
The server should reload automatically (because you added `--reload` to the `uvicorn` command above).
### Interactive API docs upgrade
Now go to <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
* The interactive API documentation will be automatically updated, including the new body:
![Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png)
* Click on the button "Try it out", it allows you to fill the parameters and directly interact with the API:
![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-04-swagger-03.png)
* Then click on the "Execute" button, the user interface will communicate with your API, send the parameters, get the results and show them on the screen:
![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-05-swagger-04.png)
### Alternative API docs upgrade
And now, go to <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
* The alternative documentation will also reflect the new query parameter and body:
![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png)
### Recap
In summary, you declare **once** the types of parameters, body, etc. as function parameters.
You do that with standard modern Python types.
You don't have to learn a new syntax, the methods or classes of a specific library, etc.
Just standard **Python 3.6+**.
For example, for an `int`:
```Python
item_id: int
```
or for a more complex `Item` model:
```Python
item: Item
```
...and with that single declaration you get:
* Editor support, including:
* Completion.
* Type checks.
* Validation of data:
* Automatic and clear errors when the data is invalid.
* Validation even for deeply nested JSON objects.
* <abbr title="also known as: serialization, parsing, marshalling">Conversion</abbr> of input data: coming from the network to Python data and types. Reading from:
* JSON.
* Path parameters.
* Query parameters.
* Cookies.
* Headers.
* Forms.
* Files.
* <abbr title="also known as: serialization, parsing, marshalling">Conversion</abbr> of output data: converting from Python data and types to network data (as JSON):
* Convert Python types (`str`, `int`, `float`, `bool`, `list`, etc).
* `datetime` objects.
* `UUID` objects.
* Database models.
* ...and many more.
* Automatic interactive API documentation, including 2 alternative user interfaces:
* Swagger UI.
* ReDoc.
---
Coming back to the previous code example, **FastAPI** will:
* Validate that there is an `item_id` in the path for `GET` and `PUT` requests.
* Validate that the `item_id` is of type `int` for `GET` and `PUT` requests.
* If it is not, the client will see a useful, clear error.
* Check if there is an optional query parameter named `q` (as in `http://127.0.0.1:8000/items/foo?q=somequery`) for `GET` requests.
* As the `q` parameter is declared with `= None`, it is optional.
* Without the `None` it would be required (as is the body in the case with `PUT`).
* For `PUT` requests to `/items/{item_id}`, Read the body as JSON:
* Check that it has a required attribute `name` that should be a `str`.
* Check that it has a required attribute `price` that has to be a `float`.
* Check that it has an optional attribute `is_offer`, that should be a `bool`, if present.
* All this would also work for deeply nested JSON objects.
* Convert from and to JSON automatically.
* Document everything with OpenAPI, that can be used by:
* Interactive documentation systems.
* Automatic client code generation systems, for many languages.
* Provide 2 interactive documentation web interfaces directly.
---
We just scratched the surface, but you already get the idea of how it all works.
Try changing the line with:
```Python
return {"item_name": item.name, "item_id": item_id}
```
...from:
```Python
... "item_name": item.name ...
```
...to:
```Python
... "item_price": item.price ...
```
...and see how your editor will auto-complete the attributes and know their types:
![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png)
For a more complete example including more features, see the <a href="https://fastapi.tiangolo.com/tutorial/">Tutorial - User Guide</a>.
**Spoiler alert**: the tutorial - user guide includes:
* Declaration of **parameters** from other different places as: **headers**, **cookies**, **form fields** and **files**.
* How to set **validation constraints** as `maximum_length` or `regex`.
* A very powerful and easy to use **<abbr title="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** system.
* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth.
* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic).
* Many extra features (thanks to Starlette) as:
* **WebSockets**
* extremely easy tests based on `requests` and `pytest`
* **CORS**
* **Cookie Sessions**
* ...and more.
## Performance
Independent TechEmpower benchmarks show **FastAPI** applications running under Uvicorn as <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">one of the fastest Python frameworks available</a>, only below Starlette and Uvicorn themselves (used internally by FastAPI). (*)
To understand more about it, see the section <a href="https://fastapi.tiangolo.com/benchmarks/" class="internal-link" target="_blank">Benchmarks</a>.
## Optional Dependencies
Used by Pydantic:
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - for faster JSON <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>.
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - for email validation.
Used by Starlette:
* <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="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).
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Required if you want to use `UJSONResponse`.
Used by FastAPI / Starlette:
* <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]`.
## License
This project is licensed under the terms of the MIT license.

136
docs/de/mkdocs.yml Normal file
View File

@@ -0,0 +1,136 @@
site_name: FastAPI
site_description: FastAPI framework, high performance, easy to learn, fast to code, ready for production
site_url: https://fastapi.tiangolo.com/de/
theme:
name: material
custom_dir: overrides
palette:
- scheme: default
primary: teal
accent: amber
toggle:
icon: material/lightbulb
name: Switch to light mode
- scheme: slate
primary: teal
accent: amber
toggle:
icon: material/lightbulb-outline
name: Switch to dark mode
features:
- search.suggest
- search.highlight
- content.tabs.link
icon:
repo: fontawesome/brands/github-alt
logo: https://fastapi.tiangolo.com/img/icon-white.svg
favicon: https://fastapi.tiangolo.com/img/favicon.png
language: de
repo_name: tiangolo/fastapi
repo_url: https://github.com/tiangolo/fastapi
edit_uri: ''
plugins:
- search
- markdownextradata:
data: data
nav:
- FastAPI: index.md
- Languages:
- en: /
- az: /az/
- de: /de/
- es: /es/
- fa: /fa/
- fr: /fr/
- id: /id/
- it: /it/
- ja: /ja/
- ko: /ko/
- nl: /nl/
- pl: /pl/
- pt: /pt/
- ru: /ru/
- sq: /sq/
- tr: /tr/
- uk: /uk/
- zh: /zh/
- features.md
markdown_extensions:
- toc:
permalink: true
- markdown.extensions.codehilite:
guess_lang: false
- mdx_include:
base_path: docs
- admonition
- codehilite
- extra
- pymdownx.superfences:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format ''
- pymdownx.tabbed:
alternate_style: true
extra:
analytics:
provider: google
property: UA-133183413-1
social:
- icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/fastapi
- icon: fontawesome/brands/discord
link: https://discord.gg/VQjSZaeJmf
- icon: fontawesome/brands/twitter
link: https://twitter.com/fastapi
- icon: fontawesome/brands/linkedin
link: https://www.linkedin.com/in/tiangolo
- icon: fontawesome/brands/dev
link: https://dev.to/tiangolo
- icon: fontawesome/brands/medium
link: https://medium.com/@tiangolo
- icon: fontawesome/solid/globe
link: https://tiangolo.com
alternate:
- link: /
name: en - English
- link: /az/
name: az
- link: /de/
name: de
- link: /es/
name: es - español
- link: /fa/
name: fa
- link: /fr/
name: fr - français
- link: /id/
name: id
- link: /it/
name: it - italiano
- link: /ja/
name: ja - 日本語
- link: /ko/
name: ko - 한국어
- link: /nl/
name: nl
- link: /pl/
name: pl
- link: /pt/
name: pt - português
- link: /ru/
name: ru - русский язык
- link: /sq/
name: sq - shqip
- link: /tr/
name: tr - Türkçe
- link: /uk/
name: uk - українська мова
- link: /zh/
name: zh - 汉语
extra_css:
- https://fastapi.tiangolo.com/css/termynal.css
- https://fastapi.tiangolo.com/css/custom.css
extra_javascript:
- https://fastapi.tiangolo.com/js/termynal.js
- https://fastapi.tiangolo.com/js/custom.js

View File

@@ -1,262 +0,0 @@
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.
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 also easily use **FastAPI** in a standard server directly too (without Docker).
## Docker
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:
```bash
docker build -t myimage .
```
### Start the Docker container
* Run a container based on your image:
```bash
docker run -d --name mycontainer -p 80:80 myimage
```
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:
* <a href="https://www.uvicorn.org/" class="external-link" target="_blank">Uvicorn</a>, a lightning-fast ASGI server, built on uvloop and httptools.
```bash
pip install uvicorn
```
* <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>, an ASGI server also compatible with HTTP/2.
```bash
pip install hypercorn
```
...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.:
```bash
uvicorn main:app --host 0.0.0.0 --port 80
```
or with Hypercorn:
```bash
hypercorn main:app --bind 0.0.0.0:80
```
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,286 @@
articles:
english:
- author: Kaustubh Gupta
author_link: https://medium.com/@kaustubhgupta1828/
link: https://www.analyticsvidhya.com/blog/2021/06/deploying-ml-models-as-api-using-fastapi-and-heroku/
title: Deploying ML Models as API Using FastAPI and Heroku
- link: https://jarmos.netlify.app/posts/using-github-actions-to-deploy-a-fastapi-project-to-heroku/
title: Using GitHub Actions to Deploy a FastAPI Project to Heroku
author_link: https://jarmos.netlify.app/
author: Somraj Saha
- author: "@pystar"
author_link: https://pystar.substack.com/
link: https://pystar.substack.com/p/how-to-create-a-fake-certificate
title: How to Create A Fake Certificate Authority And Generate TLS Certs for FastAPI
- author: Shahriyar(Shako) Rzayev
author_link: https://www.linkedin.com/in/shahriyar-rzayev/
link: https://www.azepug.az/posts/fastapi/#building-simple-e-commerce-with-nuxtjs-and-fastapi-series
title: Building simple E-Commerce with NuxtJS and FastAPI
- author: Rodrigo Arenas
author_link: https://rodrigo-arenas.medium.com/
link: https://medium.com/analytics-vidhya/serve-a-machine-learning-model-using-sklearn-fastapi-and-docker-85aabf96729b
title: "Serve a machine learning model using Sklearn, FastAPI and Docker"
- author: Navule Pavan Kumar Rao
author_link: https://www.linkedin.com/in/navule/
link: https://www.tutlinks.com/deploy-fastapi-on-ubuntu-gunicorn-caddy-2/
title: Deploy FastAPI on Ubuntu and Serve using Caddy 2 Web Server
- author: Patrick Ladon
author_link: https://dev.to/factorlive
link: https://dev.to/factorlive/python-facebook-messenger-webhook-with-fastapi-on-glitch-4n90
title: Python Facebook messenger webhook with FastAPI on Glitch
- author: Dom Patmore
author_link: https://twitter.com/dompatmore
link: https://dompatmore.com/blog/authenticate-your-fastapi-app-with-auth0
title: Authenticate Your FastAPI App with auth0
- author: Valon Januzaj
author_link: https://www.linkedin.com/in/valon-januzaj-b02692187/
link: https://valonjanuzaj.medium.com/deploy-a-dockerized-fastapi-application-to-aws-cc757830ba1b
title: Deploy a dockerized FastAPI application to AWS
- author: Amit Chaudhary
author_link: https://twitter.com/amitness
link: https://amitness.com/2020/06/fastapi-vs-flask/
title: FastAPI for Flask Users
- author: Louis Guitton
author_link: https://twitter.com/louis_guitton
link: https://guitton.co/posts/fastapi-monitoring/
title: How to monitor your FastAPI service
- author: Julien Harbulot
author_link: https://julienharbulot.com/
link: https://julienharbulot.com/notification-server.html
title: HTTP server to display desktop notifications
- author: Precious Ndubueze
author_link: https://medium.com/@gabbyprecious2000
link: https://medium.com/@gabbyprecious2000/creating-a-crud-app-with-fastapi-part-one-7c049292ad37
title: Creating a CRUD App with FastAPI (Part one)
- author: Farhad Malik
author_link: https://medium.com/@farhadmalik
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: Navule Pavan Kumar Rao
author_link: https://www.linkedin.com/in/navule/
link: https://www.tutlinks.com/deploy-fastapi-on-azure/
title: Deploy FastAPI on Azure App Service
- author: Davide Fiocco
author_link: https://github.com/davidefiocco
link: https://davidefiocco.github.io/streamlit-fastapi-ml-serving/
title: Machine learning model serving in Python using FastAPI and streamlit
- author: Netflix
author_link: https://netflixtechblog.com/
link: https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072
title: Introducing Dispatch
- author: Stavros Korokithakis
author_link: https://twitter.com/Stavros
link: https://www.stavros.io/posts/fastapi-with-django/
title: Using FastAPI with Django
- author: Twilio
author_link: https://www.twilio.com
link: https://www.twilio.com/blog/build-secure-twilio-webhook-python-fastapi
title: Build a Secure Twilio Webhook with Python and FastAPI
- author: Sebastián Ramírez (tiangolo)
author_link: https://twitter.com/tiangolo
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: Paul Sec
author_link: https://twitter.com/PaulWebSec
link: https://paulsec.github.io/posts/fastapi_plus_zeit_serverless_fu/
title: FastAPI + Zeit.co = 🚀
- author: cuongld2
author_link: https://dev.to/cuongld2
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: Paurakh Sharma Humagain
author_link: https://twitter.com/PaurakhSharma
link: https://dev.to/paurakhsharma/microservice-in-python-using-fastapi-24cc
title: Microservice in Python using FastAPI
- author: Guillermo Cruz
author_link: https://wuilly.com/
link: https://wuilly.com/2019/10/real-time-notifications-with-python-and-postgres/
title: Real-time Notifications with Python and Postgres
- author: Benjamin Ramser
author_link: https://iwpnd.pw
link: https://iwpnd.pw/articles/2020-03/apache-kafka-fastapi-geostream
title: Apache Kafka producer and consumer with FastAPI and aiokafka
- author: Navule Pavan Kumar Rao
author_link: https://www.linkedin.com/in/navule/
link: https://www.tutlinks.com/create-and-deploy-fastapi-app-to-heroku/
title: Create and Deploy FastAPI app to Heroku without using Docker
- author: Benjamin Ramser
author_link: https://iwpnd.pw
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: Arthur Henrique
author_link: https://twitter.com/arthurheinrique
link: https://medium.com/@arthur393/another-boilerplate-to-fastapi-azure-pipeline-ci-pytest-3c8d9a4be0bb
title: 'Another Boilerplate to FastAPI: Azure Pipeline CI + Pytest'
- author: Shane Soh
author_link: https://medium.com/@shane.soh
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: Mandy Gu
author_link: https://towardsdatascience.com/@mandygu
link: https://towardsdatascience.com/deploying-iris-classifications-with-fastapi-and-docker-7c9b83fdec3a
title: 'Towards Data Science: Deploying Iris Classifications with FastAPI and Docker'
- author: Michael Herman
author_link: https://testdriven.io/authors/herman
link: https://testdriven.io/blog/fastapi-crud/
title: 'TestDriven.io: Developing and Testing an Asynchronous API with FastAPI and Pytest'
- author: Bernard Brenyah
author_link: https://medium.com/@bbrenyah
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: Dylan Anthony
author_link: https://dev.to/dbanty
link: https://dev.to/dbanty/why-i-m-leaving-flask-3ki6
title: Why I'm Leaving Flask
- author: Rob Wagner
author_link: https://robwagner.dev/
link: https://robwagner.dev/tortoise-fastapi-setup/
title: Setting up Tortoise ORM with FastAPI
- author: Mike Moritz
author_link: https://medium.com/@mike.p.moritz
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: '@euri10'
author_link: https://gitlab.com/euri10
link: https://gitlab.com/euri10/fastapi_cheatsheet
title: A FastAPI and Swagger UI visual cheatsheet
- author: Uber Engineering
author_link: https://eng.uber.com
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: Maarten Grootendorst
author_link: https://www.linkedin.com/in/mgrootendorst/
link: https://towardsdatascience.com/how-to-deploy-a-machine-learning-model-dc51200fe8cf
title: How to Deploy a Machine Learning Model
- author: Johannes Gontrum
author_link: https://twitter.com/gntrm
link: https://medium.com/@gntrm/jwt-authentication-with-fastapi-and-aws-cognito-1333f7f2729e
title: JWT Authentication with FastAPI and AWS Cognito
- author: Ankush Thakur
author_link: https://geekflare.com/author/ankush/
link: https://geekflare.com/python-asynchronous-web-frameworks/
title: Top 5 Asynchronous Web Frameworks for Python
- author: Nico Axtmann
author_link: https://www.linkedin.com/in/nico-axtmann
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: Nils de Bruin
author_link: https://medium.com/@nilsdebruin
link: https://medium.com/data-rebels/fastapi-authentication-revisited-enabling-api-key-authentication-122dc5975680
title: 'FastAPI authentication revisited: Enabling API key authentication'
- author: Nick Cortale
author_link: https://nickc1.github.io/
link: https://nickc1.github.io/api,/scikit-learn/2019/01/10/scikit-fastapi.html
title: 'FastAPI and Scikit-Learn: Easily Deploy Models'
- author: Errieta Kostala
author_link: https://dev.to/errietta
link: https://dev.to/errietta/introduction-to-the-fastapi-python-framework-2n10
title: Introduction to the fastapi python framework
- author: Nils de Bruin
author_link: https://medium.com/@nilsdebruin
link: https://medium.com/data-rebels/fastapi-how-to-add-basic-and-cookie-authentication-a45c85ef47d3
title: FastAPIHow to add basic and cookie authentication
- author: Nils de Bruin
author_link: https://medium.com/@nilsdebruin
link: https://medium.com/data-rebels/fastapi-google-as-an-external-authentication-provider-3a527672cf33
title: FastAPIGoogle as an external authentication provider
- author: William Hayes
author_link: https://medium.com/@williamhayes
link: https://medium.com/@williamhayes/fastapi-starlette-debug-vs-prod-5f7561db3a59
title: FastAPI/Starlette debug vs prod
german:
- author: Nico Axtmann
author_link: https://twitter.com/_nicoax
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
japanese:
- author: '@bee2'
author_link: https://qiita.com/bee2
link: https://qiita.com/bee2/items/75d9c0d7ba20e7a4a0e9
title: '[FastAPI] Python製のASGI Web フレームワーク FastAPIに入門する'
- author: '@bee2'
author_link: https://qiita.com/bee2
link: https://qiita.com/bee2/items/0ad260ab9835a2087dae
title: PythonのWeb frameworkのパフォーマンス比較 (Django, Flask, responder, FastAPI, japronto)
- author: ライトコードメディア編集部
author_link: https://rightcode.co.jp/author/jun
link: https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-admin-page-improvement
title: '【第4回】FastAPIチュートリアル: toDoアプリを作ってみよう【管理者ページ改良編】'
- author: ライトコードメディア編集部
author_link: https://rightcode.co.jp/author/jun
link: https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-authentication-user-registration
title: '【第3回】FastAPIチュートリアル: toDoアプリを作ってみよう【認証・ユーザ登録編】'
- author: ライトコードメディア編集部
author_link: https://rightcode.co.jp/author/jun
link: https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-model-building
title: '【第2回】FastAPIチュートリアル: ToDoアプリを作ってみよう【モデル構築編】'
- author: ライトコードメディア編集部
author_link: https://rightcode.co.jp/author/jun
link: https://rightcode.co.jp/blog/information-technology/fastapi-tutorial-todo-apps-environment
title: '【第1回】FastAPIチュートリアル: ToDoアプリを作ってみよう【環境構築編】'
- author: Hikaru Takahashi
author_link: https://qiita.com/hikarut
link: https://qiita.com/hikarut/items/b178af2e2440c67c6ac4
title: フロントエンド開発者向けのDockerによるPython開発環境構築
- author: '@angel_katayoku'
author_link: https://qiita.com/angel_katayoku
link: https://qiita.com/angel_katayoku/items/8a458a8952f50b73f420
title: FastAPIでPOSTされたJSONのレスポンスbodyを受け取る
- author: '@angel_katayoku'
author_link: https://qiita.com/angel_katayoku
link: https://qiita.com/angel_katayoku/items/4fbc1a4e2b33fa2237d2
title: FastAPIをMySQLと接続してDockerで管理してみる
- author: '@angel_katayoku'
author_link: https://qiita.com/angel_katayoku
link: https://qiita.com/angel_katayoku/items/0e1f5dbbe62efc612a78
title: FastAPIでCORSを回避
- author: '@ryoryomaru'
author_link: https://qiita.com/ryoryomaru
link: https://qiita.com/ryoryomaru/items/59958ed385b3571d50de
title: python製の最新APIフレームワーク FastAPI を触ってみた
- author: '@mtitg'
author_link: https://qiita.com/mtitg
link: https://qiita.com/mtitg/items/47770e9a562dd150631d
title: FastAPIDB接続してCRUDするPython製APIサーバーを構築
russian:
- author: Troy Köhler
author_link: https://www.linkedin.com/in/trkohler/
link: https://trkohler.com/fast-api-introduction-to-framework
title: 'FastAPI: знакомимся с фреймворком'
- author: prostomarkeloff
author_link: https://github.com/prostomarkeloff
link: https://habr.com/ru/post/478620/
title: Почему Вы должны попробовать FastAPI?
- author: Andrey Korchak
author_link: https://habr.com/ru/users/57uff3r/
link: https://habr.com/ru/post/454440/
title: 'Мелкая питонячая радость #2: Starlette - Солидная примочка FastAPI'
vietnamese:
- author: Nguyễn Nhân
author_link: https://fullstackstation.com/author/figonking/
link: https://fullstackstation.com/fastapi-trien-khai-bang-docker/
title: 'FASTAPI: TRIỂN KHAI BẰNG DOCKER'
podcasts:
english:
- author: Podcast.`__init__`
author_link: https://www.pythonpodcast.com/
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: Python Bytes FM
author_link: https://pythonbytes.fm/
link: https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855
title: FastAPI on PythonBytes
talks:
english:
- author: Sebastián Ramírez (tiangolo)
author_link: https://twitter.com/tiangolo
link: https://www.youtube.com/watch?v=PnpTY1f4k2U
title: '[VIRTUAL] Py.Amsterdam''s flying Software Circus: Intro to FastAPI'
- author: Sebastián Ramírez (tiangolo)
author_link: https://twitter.com/tiangolo
link: https://www.youtube.com/watch?v=z9K5pwb0rt8
title: 'PyConBY 2020: Serve ML models easily with FastAPI'
- author: Chris Withers
author_link: https://twitter.com/chriswithers13
link: https://www.youtube.com/watch?v=3DLwPcrE5mA
title: 'PyCon UK 2019: FastAPI from the ground up'

View File

@@ -0,0 +1,508 @@
sponsors:
- - login: cryptapi
avatarUrl: https://avatars.githubusercontent.com/u/44925437?u=61369138589bc7fee6c417f3fbd50fbd38286cc4&v=4
url: https://github.com/cryptapi
- login: jina-ai
avatarUrl: https://avatars.githubusercontent.com/u/60539444?v=4
url: https://github.com/jina-ai
- - login: InesIvanova
avatarUrl: https://avatars.githubusercontent.com/u/22920417?u=409882ec1df6dbd77455788bb383a8de223dbf6f&v=4
url: https://github.com/InesIvanova
- - login: chaserowbotham
avatarUrl: https://avatars.githubusercontent.com/u/97751084?v=4
url: https://github.com/chaserowbotham
- - login: mikeckennedy
avatarUrl: https://avatars.githubusercontent.com/u/2035561?u=1bb18268bcd4d9249e1f783a063c27df9a84c05b&v=4
url: https://github.com/mikeckennedy
- login: Trivie
avatarUrl: https://avatars.githubusercontent.com/u/8161763?v=4
url: https://github.com/Trivie
- login: deta
avatarUrl: https://avatars.githubusercontent.com/u/47275976?v=4
url: https://github.com/deta
- login: deepset-ai
avatarUrl: https://avatars.githubusercontent.com/u/51827949?v=4
url: https://github.com/deepset-ai
- login: investsuite
avatarUrl: https://avatars.githubusercontent.com/u/73833632?v=4
url: https://github.com/investsuite
- - login: qaas
avatarUrl: https://avatars.githubusercontent.com/u/8503759?u=10a6b4391ad6ab4cf9487ce54e3fcb61322d1efc&v=4
url: https://github.com/qaas
- login: xoflare
avatarUrl: https://avatars.githubusercontent.com/u/74335107?v=4
url: https://github.com/xoflare
- login: Striveworks
avatarUrl: https://avatars.githubusercontent.com/u/45523576?v=4
url: https://github.com/Striveworks
- login: BoostryJP
avatarUrl: https://avatars.githubusercontent.com/u/57932412?v=4
url: https://github.com/BoostryJP
- - login: johnadjei
avatarUrl: https://avatars.githubusercontent.com/u/767860?v=4
url: https://github.com/johnadjei
- login: HiredScore
avatarUrl: https://avatars.githubusercontent.com/u/3908850?v=4
url: https://github.com/HiredScore
- login: spackle0
avatarUrl: https://avatars.githubusercontent.com/u/6148423?u=750e21b7366c0de69c305a8bcda1365d921ae477&v=4
url: https://github.com/spackle0
- login: wdwinslow
avatarUrl: https://avatars.githubusercontent.com/u/11562137?u=dc01daafb354135603a263729e3d26d939c0c452&v=4
url: https://github.com/wdwinslow
- - login: moellenbeck
avatarUrl: https://avatars.githubusercontent.com/u/169372?v=4
url: https://github.com/moellenbeck
- login: RodneyU215
avatarUrl: https://avatars.githubusercontent.com/u/3329665?u=ec6a9adf8e7e8e306eed7d49687c398608d1604f&v=4
url: https://github.com/RodneyU215
- login: grillazz
avatarUrl: https://avatars.githubusercontent.com/u/3415861?u=16d7d0ffa5dfb99f8834f8f76d90e138ba09b94a&v=4
url: https://github.com/grillazz
- login: tizz98
avatarUrl: https://avatars.githubusercontent.com/u/5739698?u=f095a3659e3a8e7c69ccd822696990b521ea25f9&v=4
url: https://github.com/tizz98
- login: jmaralc
avatarUrl: https://avatars.githubusercontent.com/u/21101214?u=b15a9f07b7cbf6c9dcdbcb6550bbd2c52f55aa50&v=4
url: https://github.com/jmaralc
- login: Filimoa
avatarUrl: https://avatars.githubusercontent.com/u/21352040?u=75e02d102d2ee3e3d793e555fa5c63045913ccb0&v=4
url: https://github.com/Filimoa
- login: marutoraman
avatarUrl: https://avatars.githubusercontent.com/u/33813153?v=4
url: https://github.com/marutoraman
- login: mainframeindustries
avatarUrl: https://avatars.githubusercontent.com/u/55092103?v=4
url: https://github.com/mainframeindustries
- login: A-Edge
avatarUrl: https://avatars.githubusercontent.com/u/59514131?v=4
url: https://github.com/A-Edge
- - login: hcristea
avatarUrl: https://avatars.githubusercontent.com/u/7814406?u=61d7a4fcf846983a4606788eac25e1c6c1209ba8&v=4
url: https://github.com/hcristea
- - login: samuelcolvin
avatarUrl: https://avatars.githubusercontent.com/u/4039449?u=807390ba9cfe23906c3bf8a0d56aaca3cf2bfa0d&v=4
url: https://github.com/samuelcolvin
- login: jokull
avatarUrl: https://avatars.githubusercontent.com/u/701?u=0532b62166893d5160ef795c4c8b7512d971af05&v=4
url: https://github.com/jokull
- login: jefftriplett
avatarUrl: https://avatars.githubusercontent.com/u/50527?u=af1ddfd50f6afd6d99f333ba2ac8d0a5b245ea74&v=4
url: https://github.com/jefftriplett
- login: kamalgill
avatarUrl: https://avatars.githubusercontent.com/u/133923?u=0df9181d97436ce330e9acf90ab8a54b7022efe7&v=4
url: https://github.com/kamalgill
- login: jsutton
avatarUrl: https://avatars.githubusercontent.com/u/280777?v=4
url: https://github.com/jsutton
- login: deserat
avatarUrl: https://avatars.githubusercontent.com/u/299332?v=4
url: https://github.com/deserat
- login: ericof
avatarUrl: https://avatars.githubusercontent.com/u/306014?u=cf7c8733620397e6584a451505581c01c5d842d7&v=4
url: https://github.com/ericof
- login: wshayes
avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
url: https://github.com/wshayes
- login: koxudaxi
avatarUrl: https://avatars.githubusercontent.com/u/630670?u=507d8577b4b3670546b449c4c2ccbc5af40d72f7&v=4
url: https://github.com/koxudaxi
- login: jqueguiner
avatarUrl: https://avatars.githubusercontent.com/u/690878?u=e4835b2a985a0f2d52018e4926cb5a58c26a62e8&v=4
url: https://github.com/jqueguiner
- login: Mazyod
avatarUrl: https://avatars.githubusercontent.com/u/860511?v=4
url: https://github.com/Mazyod
- login: ltieman
avatarUrl: https://avatars.githubusercontent.com/u/1084689?u=e69b17de17cb3ca141a17daa7ccbe173ceb1eb17&v=4
url: https://github.com/ltieman
- login: westonsteimel
avatarUrl: https://avatars.githubusercontent.com/u/1593939?u=0f2c0e3647f916fe295d62fa70da7a4c177115e3&v=4
url: https://github.com/westonsteimel
- login: timdrijvers
avatarUrl: https://avatars.githubusercontent.com/u/1694939?v=4
url: https://github.com/timdrijvers
- login: corleyma
avatarUrl: https://avatars.githubusercontent.com/u/2080732?u=aed2ff652294a87d666b1c3f6dbe98104db76d26&v=4
url: https://github.com/corleyma
- login: madisonmay
avatarUrl: https://avatars.githubusercontent.com/u/2645393?u=f22b93c6ea345a4d26a90a3834dfc7f0789fcb63&v=4
url: https://github.com/madisonmay
- login: saivarunk
avatarUrl: https://avatars.githubusercontent.com/u/2976867?u=71f4385e781e9a9e871a52f2d4686f9a8d69ba2f&v=4
url: https://github.com/saivarunk
- login: andre1sk
avatarUrl: https://avatars.githubusercontent.com/u/3148093?v=4
url: https://github.com/andre1sk
- login: Shark009
avatarUrl: https://avatars.githubusercontent.com/u/3163309?u=0c6f4091b0eda05c44c390466199826e6dc6e431&v=4
url: https://github.com/Shark009
- login: dblackrun
avatarUrl: https://avatars.githubusercontent.com/u/3528486?v=4
url: https://github.com/dblackrun
- login: zsinx6
avatarUrl: https://avatars.githubusercontent.com/u/3532625?u=ba75a5dc744d1116ccfeaaf30d41cb2fe81fe8dd&v=4
url: https://github.com/zsinx6
- login: anomaly
avatarUrl: https://avatars.githubusercontent.com/u/3654837?v=4
url: https://github.com/anomaly
- login: peterHoburg
avatarUrl: https://avatars.githubusercontent.com/u/3860655?u=f55f47eb2d6a9b495e806ac5a044e3ae01ccc1fa&v=4
url: https://github.com/peterHoburg
- login: jaredtrog
avatarUrl: https://avatars.githubusercontent.com/u/4381365?v=4
url: https://github.com/jaredtrog
- login: oliverxchen
avatarUrl: https://avatars.githubusercontent.com/u/4471774?u=534191f25e32eeaadda22dfab4b0a428733d5489&v=4
url: https://github.com/oliverxchen
- login: CINOAdam
avatarUrl: https://avatars.githubusercontent.com/u/4728508?u=76ef23f06ae7c604e009873bc27cf0ea9ba738c9&v=4
url: https://github.com/CINOAdam
- login: ScrimForever
avatarUrl: https://avatars.githubusercontent.com/u/5040124?u=091ec38bfe16d6e762099e91309b59f248616a65&v=4
url: https://github.com/ScrimForever
- login: ennui93
avatarUrl: https://avatars.githubusercontent.com/u/5300907?u=5b5452725ddb391b2caaebf34e05aba873591c3a&v=4
url: https://github.com/ennui93
- login: MacroPower
avatarUrl: https://avatars.githubusercontent.com/u/5648814?u=e13991efd1e03c44c911f919872e750530ded633&v=4
url: https://github.com/MacroPower
- login: Yaleesa
avatarUrl: https://avatars.githubusercontent.com/u/6135475?v=4
url: https://github.com/Yaleesa
- login: iwpnd
avatarUrl: https://avatars.githubusercontent.com/u/6152183?u=b2286006daafff5f991557344fee20b5da59639a&v=4
url: https://github.com/iwpnd
- login: simw
avatarUrl: https://avatars.githubusercontent.com/u/6322526?v=4
url: https://github.com/simw
- login: pkucmus
avatarUrl: https://avatars.githubusercontent.com/u/6347418?u=98f5918b32e214a168a2f5d59b0b8ebdf57dca0d&v=4
url: https://github.com/pkucmus
- login: s3ich4n
avatarUrl: https://avatars.githubusercontent.com/u/6926298?u=ba3025d698e1c986655e776ae383a3d60d9d578e&v=4
url: https://github.com/s3ich4n
- login: Rehket
avatarUrl: https://avatars.githubusercontent.com/u/7015688?u=3afb0ba200feebbc7f958950e92db34df2a3c172&v=4
url: https://github.com/Rehket
- login: christippett
avatarUrl: https://avatars.githubusercontent.com/u/7218120?u=f21f93b9c14edefef75645bf4d64c819b7d4afd7&v=4
url: https://github.com/christippett
- login: hiancdtrsnm
avatarUrl: https://avatars.githubusercontent.com/u/7343177?v=4
url: https://github.com/hiancdtrsnm
- login: Kludex
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex
- login: Shackelford-Arden
avatarUrl: https://avatars.githubusercontent.com/u/7362263?v=4
url: https://github.com/Shackelford-Arden
- login: Vikka
avatarUrl: https://avatars.githubusercontent.com/u/9381120?u=4bfc7032a824d1ed1994aa8256dfa597c8f187ad&v=4
url: https://github.com/Vikka
- login: Ge0f3
avatarUrl: https://avatars.githubusercontent.com/u/11887760?u=ccd80f1ac36dcb8517ef5c4e702e8cc5a80cad2f&v=4
url: https://github.com/Ge0f3
- login: gokulyc
avatarUrl: https://avatars.githubusercontent.com/u/13468848?u=269f269d3e70407b5fb80138c52daba7af783997&v=4
url: https://github.com/gokulyc
- login: dannywade
avatarUrl: https://avatars.githubusercontent.com/u/13680237?u=418ee985bd41577b20fde81417fb2d901e875e8a&v=4
url: https://github.com/dannywade
- login: pablonnaoji
avatarUrl: https://avatars.githubusercontent.com/u/15187159?u=afc15bd5a4ba9c5c7206bbb1bcaeef606a0932e0&v=4
url: https://github.com/pablonnaoji
- login: robintully
avatarUrl: https://avatars.githubusercontent.com/u/17059673?u=862b9bb01513f5acd30df97433cb97a24dbfb772&v=4
url: https://github.com/robintully
- login: tobiasfeil
avatarUrl: https://avatars.githubusercontent.com/u/17533713?u=bc6b0bec46f342d13c41695db90685d1c58d534e&v=4
url: https://github.com/tobiasfeil
- login: wedwardbeck
avatarUrl: https://avatars.githubusercontent.com/u/19333237?u=1de4ae2bf8d59eb4c013f21d863cbe0f2010575f&v=4
url: https://github.com/wedwardbeck
- login: linusg
avatarUrl: https://avatars.githubusercontent.com/u/19366641?u=125e390abef8fff3b3b0d370c369cba5d7fd4c67&v=4
url: https://github.com/linusg
- login: stradivari96
avatarUrl: https://avatars.githubusercontent.com/u/19752586?u=255f5f06a768f518b20cebd6963e840ac49294fd&v=4
url: https://github.com/stradivari96
- login: RedCarpetUp
avatarUrl: https://avatars.githubusercontent.com/u/20360440?v=4
url: https://github.com/RedCarpetUp
- login: shuheng-liu
avatarUrl: https://avatars.githubusercontent.com/u/22414322?u=813c45f30786c6b511b21a661def025d8f7b609e&v=4
url: https://github.com/shuheng-liu
- login: comoelcometa
avatarUrl: https://avatars.githubusercontent.com/u/25950317?u=c6751efa038561b9bc5fa56d1033d5174e10cd65&v=4
url: https://github.com/comoelcometa
- login: LarryGF
avatarUrl: https://avatars.githubusercontent.com/u/26148349?u=431bb34d36d41c172466252242175281ae132152&v=4
url: https://github.com/LarryGF
- login: veprimk
avatarUrl: https://avatars.githubusercontent.com/u/29689749?u=f8cb5a15a286e522e5b189bc572d5a1a90217fb2&v=4
url: https://github.com/veprimk
- login: orihomie
avatarUrl: https://avatars.githubusercontent.com/u/29889683?u=6bc2135a52fcb3a49e69e7d50190796618185fda&v=4
url: https://github.com/orihomie
- login: meysam81
avatarUrl: https://avatars.githubusercontent.com/u/30233243?u=64dc9fc62d039892c6fb44d804251cad5537132b&v=4
url: https://github.com/meysam81
- login: mauroalejandrojm
avatarUrl: https://avatars.githubusercontent.com/u/31569442?u=cdada990a1527926a36e95f62c30a8b48bbc49a1&v=4
url: https://github.com/mauroalejandrojm
- login: Leay15
avatarUrl: https://avatars.githubusercontent.com/u/32212558?u=c4aa9c1737e515959382a5515381757b1fd86c53&v=4
url: https://github.com/Leay15
- login: AlrasheedA
avatarUrl: https://avatars.githubusercontent.com/u/33544979?u=7fe66bf62b47682612b222e3e8f4795ef3be769b&v=4
url: https://github.com/AlrasheedA
- login: ProteinQure
avatarUrl: https://avatars.githubusercontent.com/u/33707203?v=4
url: https://github.com/ProteinQure
- login: guligon90
avatarUrl: https://avatars.githubusercontent.com/u/35070513?u=b48c05f669d1ea1d329f90dc70e45f10b569ef55&v=4
url: https://github.com/guligon90
- login: ybressler
avatarUrl: https://avatars.githubusercontent.com/u/40807730?u=6621dc9ab53b697912ab2a32211bb29ae90a9112&v=4
url: https://github.com/ybressler
- login: dbanty
avatarUrl: https://avatars.githubusercontent.com/u/43723790?u=9bcce836bbce55835291c5b2ac93a4e311f4b3c3&v=4
url: https://github.com/dbanty
- login: rafsaf
avatarUrl: https://avatars.githubusercontent.com/u/51059348?u=be9f06b8ced2d2b677297decc781fa8ce4f7ddbd&v=4
url: https://github.com/rafsaf
- login: dudikbender
avatarUrl: https://avatars.githubusercontent.com/u/53487583?u=494f85229115076121b3639a3806bbac1c6ae7f6&v=4
url: https://github.com/dudikbender
- login: daisuke8000
avatarUrl: https://avatars.githubusercontent.com/u/55035595?u=5025e379cd3655ae1a96039efc85223a873d2e38&v=4
url: https://github.com/daisuke8000
- login: primer-io
avatarUrl: https://avatars.githubusercontent.com/u/62146168?v=4
url: https://github.com/primer-io
- login: around
avatarUrl: https://avatars.githubusercontent.com/u/62425723?v=4
url: https://github.com/around
- login: predictionmachine
avatarUrl: https://avatars.githubusercontent.com/u/63719559?v=4
url: https://github.com/predictionmachine
- login: daverin
avatarUrl: https://avatars.githubusercontent.com/u/70378377?u=6d1814195c0de7162820eaad95a25b423a3869c0&v=4
url: https://github.com/daverin
- login: anthonycepeda
avatarUrl: https://avatars.githubusercontent.com/u/72019805?u=892f700c79f9732211bd5221bf16eec32356a732&v=4
url: https://github.com/anthonycepeda
- login: abdurrahim84
avatarUrl: https://avatars.githubusercontent.com/u/79488613?v=4
url: https://github.com/abdurrahim84
- login: NinaHwang
avatarUrl: https://avatars.githubusercontent.com/u/79563565?u=1741703bd6c8f491503354b363a86e879b4c1cab&v=4
url: https://github.com/NinaHwang
- login: dotlas
avatarUrl: https://avatars.githubusercontent.com/u/88832003?v=4
url: https://github.com/dotlas
- login: pyt3h
avatarUrl: https://avatars.githubusercontent.com/u/99658549?v=4
url: https://github.com/pyt3h
- - login: '837477'
avatarUrl: https://avatars.githubusercontent.com/u/37999795?u=543b0bd0e8f283db0fc50754e5d13f6afba8cbea&v=4
url: https://github.com/837477
- - login: linux-china
avatarUrl: https://avatars.githubusercontent.com/u/46711?v=4
url: https://github.com/linux-china
- login: ddanier
avatarUrl: https://avatars.githubusercontent.com/u/113563?v=4
url: https://github.com/ddanier
- login: jhb
avatarUrl: https://avatars.githubusercontent.com/u/142217?v=4
url: https://github.com/jhb
- login: justinrmiller
avatarUrl: https://avatars.githubusercontent.com/u/143998?u=b507a940394d4fc2bc1c27cea2ca9c22538874bd&v=4
url: https://github.com/justinrmiller
- login: bryanculbertson
avatarUrl: https://avatars.githubusercontent.com/u/144028?u=defda4f90e93429221cc667500944abde60ebe4a&v=4
url: https://github.com/bryanculbertson
- login: yourkin
avatarUrl: https://avatars.githubusercontent.com/u/178984?u=fa7c3503b47bf16405b96d21554bc59f07a65523&v=4
url: https://github.com/yourkin
- login: slafs
avatarUrl: https://avatars.githubusercontent.com/u/210173?v=4
url: https://github.com/slafs
- login: assem-ch
avatarUrl: https://avatars.githubusercontent.com/u/315228?u=e0c5ab30726d3243a40974bb9bae327866e42d9b&v=4
url: https://github.com/assem-ch
- login: adamghill
avatarUrl: https://avatars.githubusercontent.com/u/317045?u=f1349d5ffe84a19f324e204777859fbf69ddf633&v=4
url: https://github.com/adamghill
- login: eteq
avatarUrl: https://avatars.githubusercontent.com/u/346587?v=4
url: https://github.com/eteq
- login: dmig
avatarUrl: https://avatars.githubusercontent.com/u/388564?v=4
url: https://github.com/dmig
- login: rinckd
avatarUrl: https://avatars.githubusercontent.com/u/546002?u=1fcc7e664dc86524a0af6837a0c222829c3fd4e5&v=4
url: https://github.com/rinckd
- login: securancy
avatarUrl: https://avatars.githubusercontent.com/u/606673?v=4
url: https://github.com/securancy
- login: falkben
avatarUrl: https://avatars.githubusercontent.com/u/653031?u=0c8d8f33d87f1aa1a6488d3f02105e9abc838105&v=4
url: https://github.com/falkben
- login: hardbyte
avatarUrl: https://avatars.githubusercontent.com/u/855189?u=aa29e92f34708814d6b67fcd47ca4cf2ce1c04ed&v=4
url: https://github.com/hardbyte
- login: clstaudt
avatarUrl: https://avatars.githubusercontent.com/u/875194?u=46a92f9f837d0ba150ae0f1d91091dd2f4ebb6cc&v=4
url: https://github.com/clstaudt
- login: scari
avatarUrl: https://avatars.githubusercontent.com/u/964251?v=4
url: https://github.com/scari
- login: Pytlicek
avatarUrl: https://avatars.githubusercontent.com/u/1430522?u=169dba3bfbc04ed214a914640ff435969f19ddb3&v=4
url: https://github.com/Pytlicek
- login: Celeborn2BeAlive
avatarUrl: https://avatars.githubusercontent.com/u/1659465?u=944517e4db0f6df65070074e81cabdad9c8a434b&v=4
url: https://github.com/Celeborn2BeAlive
- login: WillHogan
avatarUrl: https://avatars.githubusercontent.com/u/1661551?u=7036c064cf29781470573865264ec8e60b6b809f&v=4
url: https://github.com/WillHogan
- login: cbonoz
avatarUrl: https://avatars.githubusercontent.com/u/2351087?u=fd3e8030b2cc9fbfbb54a65e9890c548a016f58b&v=4
url: https://github.com/cbonoz
- login: Abbe98
avatarUrl: https://avatars.githubusercontent.com/u/2631719?u=8a064aba9a710229ad28c616549d81a24191a5df&v=4
url: https://github.com/Abbe98
- login: rglsk
avatarUrl: https://avatars.githubusercontent.com/u/2768101?u=e349c88673f2155fe021331377c656a9d74bcc25&v=4
url: https://github.com/rglsk
- login: paul121
avatarUrl: https://avatars.githubusercontent.com/u/3116995?u=6e2d8691cc345e63ee02e4eb4d7cef82b1fcbedc&v=4
url: https://github.com/paul121
- login: igorcorrea
avatarUrl: https://avatars.githubusercontent.com/u/3438238?u=c57605077c31a8f7b2341fc4912507f91b4a5621&v=4
url: https://github.com/igorcorrea
- login: anthonycorletti
avatarUrl: https://avatars.githubusercontent.com/u/3477132?v=4
url: https://github.com/anthonycorletti
- login: pawamoy
avatarUrl: https://avatars.githubusercontent.com/u/3999221?u=b030e4c89df2f3a36bc4710b925bdeb6745c9856&v=4
url: https://github.com/pawamoy
- login: Alisa-lisa
avatarUrl: https://avatars.githubusercontent.com/u/4137964?u=e7e393504f554f4ff15863a1e01a5746863ef9ce&v=4
url: https://github.com/Alisa-lisa
- login: unredundant
avatarUrl: https://avatars.githubusercontent.com/u/5607577?u=57dd0023365bec03f4fc566df6b81bc0a264a47d&v=4
url: https://github.com/unredundant
- login: holec
avatarUrl: https://avatars.githubusercontent.com/u/6438041?u=f5af71ec85b3a9d7b8139cb5af0512b02fa9ab1e&v=4
url: https://github.com/holec
- login: davanstrien
avatarUrl: https://avatars.githubusercontent.com/u/8995957?u=fb2aad2b52bb4e7b56db6d7c8ecc9ae1eac1b984&v=4
url: https://github.com/davanstrien
- login: and-semakin
avatarUrl: https://avatars.githubusercontent.com/u/9129071?u=ea77ddf7de4bc375d546bf2825ed420eaddb7666&v=4
url: https://github.com/and-semakin
- login: yenchenLiu
avatarUrl: https://avatars.githubusercontent.com/u/9199638?u=8cdf5ae507448430d90f6f3518d1665a23afe99b&v=4
url: https://github.com/yenchenLiu
- login: VivianSolide
avatarUrl: https://avatars.githubusercontent.com/u/9358572?u=4a38ef72dd39e8b262bd5ab819992128b55c52b4&v=4
url: https://github.com/VivianSolide
- login: xncbf
avatarUrl: https://avatars.githubusercontent.com/u/9462045?u=866a1311e4bd3ec5ae84185c4fcc99f397c883d7&v=4
url: https://github.com/xncbf
- login: DMantis
avatarUrl: https://avatars.githubusercontent.com/u/9536869?v=4
url: https://github.com/DMantis
- login: hard-coders
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
url: https://github.com/hard-coders
- login: pheanex
avatarUrl: https://avatars.githubusercontent.com/u/10408624?u=5b6bab6ee174aa6e991333e06eb29f628741013d&v=4
url: https://github.com/pheanex
- login: JimFawkes
avatarUrl: https://avatars.githubusercontent.com/u/12075115?u=dc58ecfd064d72887c34bf500ddfd52592509acd&v=4
url: https://github.com/JimFawkes
- login: logan-connolly
avatarUrl: https://avatars.githubusercontent.com/u/16244943?u=8ae66dfbba936463cc8aa0dd7a6d2b4c0cc757eb&v=4
url: https://github.com/logan-connolly
- login: cdsre
avatarUrl: https://avatars.githubusercontent.com/u/16945936?v=4
url: https://github.com/cdsre
- login: jangia
avatarUrl: https://avatars.githubusercontent.com/u/17927101?u=9261b9bb0c3e3bb1ecba43e8915dc58d8c9a077e&v=4
url: https://github.com/jangia
- login: ghandic
avatarUrl: https://avatars.githubusercontent.com/u/23500353?u=e2e1d736f924d9be81e8bfc565b6d8836ba99773&v=4
url: https://github.com/ghandic
- login: fstau
avatarUrl: https://avatars.githubusercontent.com/u/24669867?u=60e7c8c09f8dafabee8fc3edcd6f9e19abbff918&v=4
url: https://github.com/fstau
- login: mertguvencli
avatarUrl: https://avatars.githubusercontent.com/u/29762151?u=16a906d90df96c8cff9ea131a575c4bc171b1523&v=4
url: https://github.com/mertguvencli
- login: dwreeves
avatarUrl: https://avatars.githubusercontent.com/u/31971762?u=69732aba05aa5cf0780866349ebe109cf632b047&v=4
url: https://github.com/dwreeves
- login: kitaramu0401
avatarUrl: https://avatars.githubusercontent.com/u/33246506?u=929e6efa2c518033b8097ba524eb5347a069bb3b&v=4
url: https://github.com/kitaramu0401
- login: engineerjoe440
avatarUrl: https://avatars.githubusercontent.com/u/33275230?u=eb223cad27017bb1e936ee9b429b450d092d0236&v=4
url: https://github.com/engineerjoe440
- login: declon
avatarUrl: https://avatars.githubusercontent.com/u/36180226?v=4
url: https://github.com/declon
- login: d-e-h-i-o
avatarUrl: https://avatars.githubusercontent.com/u/36816716?v=4
url: https://github.com/d-e-h-i-o
- login: askurihin
avatarUrl: https://avatars.githubusercontent.com/u/37978981?v=4
url: https://github.com/askurihin
- login: ilias-ant
avatarUrl: https://avatars.githubusercontent.com/u/42189572?u=a2d6121bac4d125d92ec207460fa3f1842d37e66&v=4
url: https://github.com/ilias-ant
- login: arrrrrmin
avatarUrl: https://avatars.githubusercontent.com/u/43553423?u=fee5739394fea074cb0b66929d070114a5067aae&v=4
url: https://github.com/arrrrrmin
- login: igorezersky
avatarUrl: https://avatars.githubusercontent.com/u/46680020?u=a20a595c881dbe5658c906fecc7eff125efb4fd4&v=4
url: https://github.com/igorezersky
- login: akanz1
avatarUrl: https://avatars.githubusercontent.com/u/51492342?u=2280f57134118714645e16b535c1a37adf6b369b&v=4
url: https://github.com/akanz1
- login: rooflexx
avatarUrl: https://avatars.githubusercontent.com/u/58993673?u=f8ba450460f1aea18430ed1e4a3889049a3b4dfa&v=4
url: https://github.com/rooflexx
- login: denisyao1
avatarUrl: https://avatars.githubusercontent.com/u/60019356?v=4
url: https://github.com/denisyao1
- login: apar-tiwari
avatarUrl: https://avatars.githubusercontent.com/u/61064197?v=4
url: https://github.com/apar-tiwari
- login: 0417taehyun
avatarUrl: https://avatars.githubusercontent.com/u/63915557?u=47debaa860fd52c9b98c97ef357ddcec3b3fb399&v=4
url: https://github.com/0417taehyun
- login: alessio-proietti
avatarUrl: https://avatars.githubusercontent.com/u/67370599?u=8ac73db1e18e946a7681f173abdb640516f88515&v=4
url: https://github.com/alessio-proietti
- - login: spyker77
avatarUrl: https://avatars.githubusercontent.com/u/4953435?u=03c724c6f8fbab5cd6575b810c0c91c652fa4f79&v=4
url: https://github.com/spyker77
- login: backbord
avatarUrl: https://avatars.githubusercontent.com/u/6814946?v=4
url: https://github.com/backbord
- login: sadikkuzu
avatarUrl: https://avatars.githubusercontent.com/u/23168063?u=765ed469c44c004560079210ccdad5b29938eaa9&v=4
url: https://github.com/sadikkuzu
- login: MoronVV
avatarUrl: https://avatars.githubusercontent.com/u/24293616?v=4
url: https://github.com/MoronVV
- login: gabrielmbmb
avatarUrl: https://avatars.githubusercontent.com/u/29572918?u=92084ed7242160dee4d20aece923a10c59758ee5&v=4
url: https://github.com/gabrielmbmb
- login: danburonline
avatarUrl: https://avatars.githubusercontent.com/u/34251194?u=2cad4388c1544e539ecb732d656e42fb07b4ff2d&v=4
url: https://github.com/danburonline

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

@@ -0,0 +1,502 @@
maintainers:
- login: tiangolo
answers: 1240
prs: 291
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=5cad72c846b7aba2e960546af490edc7375dafc4&v=4
url: https://github.com/tiangolo
experts:
- login: Kludex
count: 330
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex
- login: dmontagu
count: 262
avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=58ed2a45798a4339700e2f62b2e12e6e54bf0396&v=4
url: https://github.com/dmontagu
- login: ycd
count: 221
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=826f228edf0bab0d19ad1d5c4ba4df1047ccffef&v=4
url: https://github.com/ycd
- login: Mause
count: 207
avatarUrl: https://avatars.githubusercontent.com/u/1405026?v=4
url: https://github.com/Mause
- login: euri10
count: 166
avatarUrl: https://avatars.githubusercontent.com/u/1104190?u=321a2e953e6645a7d09b732786c7a8061e0f8a8b&v=4
url: https://github.com/euri10
- login: phy25
count: 130
avatarUrl: https://avatars.githubusercontent.com/u/331403?v=4
url: https://github.com/phy25
- login: raphaelauv
count: 71
avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
url: https://github.com/raphaelauv
- login: ArcLightSlavik
count: 71
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=81a84af39c89b898b0fbc5a04e8834f60f23e55a&v=4
url: https://github.com/ArcLightSlavik
- login: falkben
count: 58
avatarUrl: https://avatars.githubusercontent.com/u/653031?u=0c8d8f33d87f1aa1a6488d3f02105e9abc838105&v=4
url: https://github.com/falkben
- login: sm-Fifteen
count: 48
avatarUrl: https://avatars.githubusercontent.com/u/516999?u=437c0c5038558c67e887ccd863c1ba0f846c03da&v=4
url: https://github.com/sm-Fifteen
- login: insomnes
count: 46
avatarUrl: https://avatars.githubusercontent.com/u/16958893?u=f8be7088d5076d963984a21f95f44e559192d912&v=4
url: https://github.com/insomnes
- login: Dustyposa
count: 43
avatarUrl: https://avatars.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4
url: https://github.com/Dustyposa
- login: includeamin
count: 39
avatarUrl: https://avatars.githubusercontent.com/u/11836741?u=8bd5ef7e62fe6a82055e33c4c0e0a7879ff8cfb6&v=4
url: https://github.com/includeamin
- login: STeveShary
count: 37
avatarUrl: https://avatars.githubusercontent.com/u/5167622?u=de8f597c81d6336fcebc37b32dfd61a3f877160c&v=4
url: https://github.com/STeveShary
- login: prostomarkeloff
count: 33
avatarUrl: https://avatars.githubusercontent.com/u/28061158?u=72309cc1f2e04e40fa38b29969cb4e9d3f722e7b&v=4
url: https://github.com/prostomarkeloff
- login: frankie567
count: 31
avatarUrl: https://avatars.githubusercontent.com/u/1144727?u=85c025e3fcc7bd79a5665c63ee87cdf8aae13374&v=4
url: https://github.com/frankie567
- login: adriangb
count: 31
avatarUrl: https://avatars.githubusercontent.com/u/1755071?u=81f0262df34e1460ca546fbd0c211169c2478532&v=4
url: https://github.com/adriangb
- login: krishnardt
count: 31
avatarUrl: https://avatars.githubusercontent.com/u/31960541?u=47f4829c77f4962ab437ffb7995951e41eeebe9b&v=4
url: https://github.com/krishnardt
- login: wshayes
count: 29
avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
url: https://github.com/wshayes
- login: chbndrhnns
count: 26
avatarUrl: https://avatars.githubusercontent.com/u/7534547?v=4
url: https://github.com/chbndrhnns
- login: panla
count: 26
avatarUrl: https://avatars.githubusercontent.com/u/41326348?u=ba2fda6b30110411ecbf406d187907e2b420ac19&v=4
url: https://github.com/panla
- login: ghandic
count: 25
avatarUrl: https://avatars.githubusercontent.com/u/23500353?u=e2e1d736f924d9be81e8bfc565b6d8836ba99773&v=4
url: https://github.com/ghandic
- login: dbanty
count: 25
avatarUrl: https://avatars.githubusercontent.com/u/43723790?u=9bcce836bbce55835291c5b2ac93a4e311f4b3c3&v=4
url: https://github.com/dbanty
- login: SirTelemak
count: 24
avatarUrl: https://avatars.githubusercontent.com/u/9435877?u=719327b7d2c4c62212456d771bfa7c6b8dbb9eac&v=4
url: https://github.com/SirTelemak
- login: jgould22
count: 23
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
url: https://github.com/jgould22
- login: acnebs
count: 22
avatarUrl: https://avatars.githubusercontent.com/u/9054108?u=c27e50269f1ef8ea950cc6f0268c8ec5cebbe9c9&v=4
url: https://github.com/acnebs
- login: nsidnev
count: 22
avatarUrl: https://avatars.githubusercontent.com/u/22559461?u=a9cc3238217e21dc8796a1a500f01b722adb082c&v=4
url: https://github.com/nsidnev
- login: chris-allnutt
count: 21
avatarUrl: https://avatars.githubusercontent.com/u/565544?v=4
url: https://github.com/chris-allnutt
- login: retnikt
count: 19
avatarUrl: https://avatars.githubusercontent.com/u/24581770?v=4
url: https://github.com/retnikt
- login: acidjunk
count: 18
avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
url: https://github.com/acidjunk
- login: Hultner
count: 18
avatarUrl: https://avatars.githubusercontent.com/u/2669034?u=115e53df959309898ad8dc9443fbb35fee71df07&v=4
url: https://github.com/Hultner
- login: jorgerpo
count: 17
avatarUrl: https://avatars.githubusercontent.com/u/12537771?u=7444d20019198e34911082780cc7ad73f2b97cb3&v=4
url: https://github.com/jorgerpo
- login: nkhitrov
count: 17
avatarUrl: https://avatars.githubusercontent.com/u/28262306?u=66ee21316275ef356081c2efc4ed7a4572e690dc&v=4
url: https://github.com/nkhitrov
- login: harunyasar
count: 17
avatarUrl: https://avatars.githubusercontent.com/u/1765494?u=5b1ab7c582db4b4016fa31affe977d10af108ad4&v=4
url: https://github.com/harunyasar
- login: waynerv
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
url: https://github.com/waynerv
- login: dstlny
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/41964673?u=9f2174f9d61c15c6e3a4c9e3aeee66f711ce311f&v=4
url: https://github.com/dstlny
- login: rafsaf
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/51059348?u=be9f06b8ced2d2b677297decc781fa8ce4f7ddbd&v=4
url: https://github.com/rafsaf
- login: haizaar
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/58201?u=4f1f9843d69433ca0d380d95146cfe119e5fdac4&v=4
url: https://github.com/haizaar
- login: hellocoldworld
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/47581948?v=4
url: https://github.com/hellocoldworld
- login: David-Lor
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/17401854?u=474680c02b94cba810cb9032fb7eb787d9cc9d22&v=4
url: https://github.com/David-Lor
- login: lowercase00
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/21188280?v=4
url: https://github.com/lowercase00
- login: zamiramir
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/40475662?u=e58ef61034e8d0d6a312cc956fb09b9c3332b449&v=4
url: https://github.com/zamiramir
- login: juntatalor
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/8134632?v=4
url: https://github.com/juntatalor
- login: valentin994
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/42819267?u=fdeeaa9242a59b243f8603496b00994f6951d5a2&v=4
url: https://github.com/valentin994
- login: aalifadv
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/78442260?v=4
url: https://github.com/aalifadv
- login: stefanondisponibile
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/20441825?u=ee1e59446b98f8ec2363caeda4c17164d0d9cc7d&v=4
url: https://github.com/stefanondisponibile
- login: oligond
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/2858306?u=1bb1182a5944e93624b7fb26585f22c8f7a9d76e&v=4
url: https://github.com/oligond
- login: n8sty
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/2964996?v=4
url: https://github.com/n8sty
last_month_active:
- login: yinziyan1206
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/37829370?v=4
url: https://github.com/yinziyan1206
- login: Kludex
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex
- login: jd-0001
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/47495003?u=322eedc0931b62827cf5f239654f77bfaff76b46&v=4
url: https://github.com/jd-0001
- login: harunyasar
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/1765494?u=5b1ab7c582db4b4016fa31affe977d10af108ad4&v=4
url: https://github.com/harunyasar
- login: wmcgee3
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/61711986?u=c51ebfaf8a995019fda8288690f4a009ecf070f0&v=4
url: https://github.com/wmcgee3
- login: tasercake
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/13855549?v=4
url: https://github.com/tasercake
- login: jgould22
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
url: https://github.com/jgould22
top_contributors:
- login: waynerv
count: 25
avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
url: https://github.com/waynerv
- login: tokusumi
count: 22
avatarUrl: https://avatars.githubusercontent.com/u/41147016?u=55010621aece725aa702270b54fed829b6a1fe60&v=4
url: https://github.com/tokusumi
- login: dmontagu
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=58ed2a45798a4339700e2f62b2e12e6e54bf0396&v=4
url: https://github.com/dmontagu
- login: jaystone776
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/11191137?u=299205a95e9b6817a43144a48b643346a5aac5cc&v=4
url: https://github.com/jaystone776
- login: euri10
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/1104190?u=321a2e953e6645a7d09b732786c7a8061e0f8a8b&v=4
url: https://github.com/euri10
- login: mariacamilagl
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/11489395?u=4adb6986bf3debfc2b8216ae701f2bd47d73da7d&v=4
url: https://github.com/mariacamilagl
- login: Smlep
count: 9
avatarUrl: https://avatars.githubusercontent.com/u/16785985?v=4
url: https://github.com/Smlep
- login: Serrones
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/22691749?u=4795b880e13ca33a73e52fc0ef7dc9c60c8fce47&v=4
url: https://github.com/Serrones
- login: RunningIkkyu
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/31848542?u=706e1ee3f248245f2d68b976d149d06fd5a2010d&v=4
url: https://github.com/RunningIkkyu
- login: Kludex
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex
- login: hard-coders
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
url: https://github.com/hard-coders
- login: wshayes
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
url: https://github.com/wshayes
- login: SwftAlpc
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/52768429?u=6a3aa15277406520ad37f6236e89466ed44bc5b8&v=4
url: https://github.com/SwftAlpc
- login: Attsun1031
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/1175560?v=4
url: https://github.com/Attsun1031
- login: jekirl
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/2546697?u=a027452387d85bd4a14834e19d716c99255fb3b7&v=4
url: https://github.com/jekirl
- login: jfunez
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/805749?v=4
url: https://github.com/jfunez
- login: ycd
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=826f228edf0bab0d19ad1d5c4ba4df1047ccffef&v=4
url: https://github.com/ycd
- login: komtaki
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/39375566?u=260ad6b1a4b34c07dbfa728da5e586f16f6d1824&v=4
url: https://github.com/komtaki
- login: NinaHwang
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/79563565?u=1741703bd6c8f491503354b363a86e879b4c1cab&v=4
url: https://github.com/NinaHwang
top_reviewers:
- login: Kludex
count: 93
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex
- login: waynerv
count: 47
avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
url: https://github.com/waynerv
- login: Laineyzhang55
count: 47
avatarUrl: https://avatars.githubusercontent.com/u/59285379?v=4
url: https://github.com/Laineyzhang55
- login: tokusumi
count: 46
avatarUrl: https://avatars.githubusercontent.com/u/41147016?u=55010621aece725aa702270b54fed829b6a1fe60&v=4
url: https://github.com/tokusumi
- login: ycd
count: 45
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=826f228edf0bab0d19ad1d5c4ba4df1047ccffef&v=4
url: https://github.com/ycd
- login: cikay
count: 41
avatarUrl: https://avatars.githubusercontent.com/u/24587499?u=e772190a051ab0eaa9c8542fcff1892471638f2b&v=4
url: https://github.com/cikay
- login: AdrianDeAnda
count: 33
avatarUrl: https://avatars.githubusercontent.com/u/1024932?u=bb7f8a0d6c9de4e9d0320a9f271210206e202250&v=4
url: https://github.com/AdrianDeAnda
- login: ArcLightSlavik
count: 31
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=81a84af39c89b898b0fbc5a04e8834f60f23e55a&v=4
url: https://github.com/ArcLightSlavik
- login: BilalAlpaslan
count: 28
avatarUrl: https://avatars.githubusercontent.com/u/47563997?u=63ed66e304fe8d765762c70587d61d9196e5c82d&v=4
url: https://github.com/BilalAlpaslan
- login: dmontagu
count: 23
avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=58ed2a45798a4339700e2f62b2e12e6e54bf0396&v=4
url: https://github.com/dmontagu
- login: cassiobotaro
count: 23
avatarUrl: https://avatars.githubusercontent.com/u/3127847?u=b0a652331da17efeb85cd6e3a4969182e5004804&v=4
url: https://github.com/cassiobotaro
- login: komtaki
count: 21
avatarUrl: https://avatars.githubusercontent.com/u/39375566?u=260ad6b1a4b34c07dbfa728da5e586f16f6d1824&v=4
url: https://github.com/komtaki
- login: hard-coders
count: 19
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
url: https://github.com/hard-coders
- login: 0417taehyun
count: 19
avatarUrl: https://avatars.githubusercontent.com/u/63915557?u=47debaa860fd52c9b98c97ef357ddcec3b3fb399&v=4
url: https://github.com/0417taehyun
- login: zy7y
count: 17
avatarUrl: https://avatars.githubusercontent.com/u/67154681?u=5d634834cc514028ea3f9115f7030b99a1f4d5a4&v=4
url: https://github.com/zy7y
- login: yezz123
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/52716203?u=636b4f79645176df4527dd45c12d5dbb5a4193cf&v=4
url: https://github.com/yezz123
- login: yanever
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/21978760?v=4
url: https://github.com/yanever
- login: lsglucas
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/61513630?u=320e43fe4dc7bc6efc64e9b8f325f8075634fd20&v=4
url: https://github.com/lsglucas
- login: SwftAlpc
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/52768429?u=6a3aa15277406520ad37f6236e89466ed44bc5b8&v=4
url: https://github.com/SwftAlpc
- login: Smlep
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/16785985?v=4
url: https://github.com/Smlep
- login: DevDae
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/87962045?u=08e10fa516e844934f4b3fc7c38b33c61697e4a1&v=4
url: https://github.com/DevDae
- login: pedabraham
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/16860088?u=abf922a7b920bf8fdb7867d8b43e091f1e796178&v=4
url: https://github.com/pedabraham
- login: delhi09
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/63476957?u=6c86e59b48e0394d4db230f37fc9ad4d7e2c27c7&v=4
url: https://github.com/delhi09
- login: rjNemo
count: 14
avatarUrl: https://avatars.githubusercontent.com/u/56785022?u=d5c3a02567c8649e146fcfc51b6060ccaf8adef8&v=4
url: https://github.com/rjNemo
- login: RunningIkkyu
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/31848542?u=706e1ee3f248245f2d68b976d149d06fd5a2010d&v=4
url: https://github.com/RunningIkkyu
- login: sh0nk
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/6478810?u=af15d724875cec682ed8088a86d36b2798f981c0&v=4
url: https://github.com/sh0nk
- login: mariacamilagl
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/11489395?u=4adb6986bf3debfc2b8216ae701f2bd47d73da7d&v=4
url: https://github.com/mariacamilagl
- login: Attsun1031
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/1175560?v=4
url: https://github.com/Attsun1031
- login: maoyibo
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/7887703?v=4
url: https://github.com/maoyibo
- login: solomein-sv
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/46193920?u=46acfb4aeefb1d7b9fdc5a8cbd9eb8744683c47a&v=4
url: https://github.com/solomein-sv
- login: graingert
count: 9
avatarUrl: https://avatars.githubusercontent.com/u/413772?v=4
url: https://github.com/graingert
- login: PandaHun
count: 9
avatarUrl: https://avatars.githubusercontent.com/u/13096845?u=646eba44db720e37d0dbe8e98e77ab534ea78a20&v=4
url: https://github.com/PandaHun
- login: kty4119
count: 9
avatarUrl: https://avatars.githubusercontent.com/u/49435654?v=4
url: https://github.com/kty4119
- login: bezaca
count: 9
avatarUrl: https://avatars.githubusercontent.com/u/69092910?u=4ac58eab99bd37d663f3d23551df96d4fbdbf760&v=4
url: https://github.com/bezaca
- login: blt232018
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/43393471?u=172b0e0391db1aa6c1706498d6dfcb003c8a4857&v=4
url: https://github.com/blt232018
- login: rogerbrinkmann
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/5690226?v=4
url: https://github.com/rogerbrinkmann
- login: ComicShrimp
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/43503750?u=b3e4d9a14d9a65d429ce62c566aef73178b7111d&v=4
url: https://github.com/ComicShrimp
- login: dimaqq
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/662249?v=4
url: https://github.com/dimaqq
- login: Serrones
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/22691749?u=4795b880e13ca33a73e52fc0ef7dc9c60c8fce47&v=4
url: https://github.com/Serrones
- login: ryuckel
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/36391432?u=094eec0cfddd5013f76f31e55e56147d78b19553&v=4
url: https://github.com/ryuckel
- login: raphaelauv
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
url: https://github.com/raphaelauv
- login: NastasiaSaby
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/8245071?u=b3afd005f9e4bf080c219ef61a592b3a8004b764&v=4
url: https://github.com/NastasiaSaby
- login: Mause
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/1405026?v=4
url: https://github.com/Mause
- login: krocdort
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/34248814?v=4
url: https://github.com/krocdort
- login: NinaHwang
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/79563565?u=1741703bd6c8f491503354b363a86e879b4c1cab&v=4
url: https://github.com/NinaHwang
- login: jovicon
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/21287303?u=b049eac3e51a4c0473c2efe66b4d28a7d8f2b572&v=4
url: https://github.com/jovicon
- login: LorhanSohaky
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/16273730?u=095b66f243a2cd6a0aadba9a095009f8aaf18393&v=4
url: https://github.com/LorhanSohaky
- login: peidrao
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/32584628?u=88c2cb42a99e0f50cdeae3606992568184783ee5&v=4
url: https://github.com/peidrao
- login: diogoduartec
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/31852339?u=b50fc11c531e9b77922e19edfc9e7233d4d7b92e&v=4
url: https://github.com/diogoduartec

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

@@ -0,0 +1,36 @@
gold:
- url: https://bit.ly/2QSouzH
title: "Jina: build neural search-as-a-service for any kind of data in just minutes."
img: https://fastapi.tiangolo.com/img/sponsors/jina.svg
- url: https://cryptapi.io/
title: "CryptAPI: Your easy to use, secure and privacy oriented payment gateway."
img: https://fastapi.tiangolo.com/img/sponsors/cryptapi.svg
- url: https://classiq.link/n4s
title: Join the team building a new SaaS platform that will change the computing world
img: https://fastapi.tiangolo.com/img/sponsors/classiq.png
silver:
- 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
- url: https://www.investsuite.com/jobs
title: Wealthtech jobs with FastAPI
img: https://fastapi.tiangolo.com/img/sponsors/investsuite.svg
- url: https://talkpython.fm/fastapi-sponsor
title: FastAPI video courses on demand from people you trust
img: https://fastapi.tiangolo.com/img/sponsors/talkpython.png
- url: https://testdriven.io/courses/tdd-fastapi/
title: Learn to build high-quality web apps with best practices
img: https://fastapi.tiangolo.com/img/sponsors/testdriven.svg
- url: https://github.com/deepset-ai/haystack/
title: Build powerful search from composable, open source building blocks
img: https://fastapi.tiangolo.com/img/sponsors/haystack-fastapi.svg
- url: https://www.udemy.com/course/fastapi-rest/
title: Learn FastAPI by building a complete project. Extend your knowledge on advanced web development-AWS, Payments, Emails.
img: https://fastapi.tiangolo.com/img/sponsors/ines-course.jpg
bronze:
- url: https://www.exoflare.com/open-source/?utm_source=FastAPI&utm_campaign=open_source
title: Biosecurity risk assessments made easy.
img: https://fastapi.tiangolo.com/img/sponsors/exoflare.png
- url: https://striveworks.us/careers?utm_source=fastapi&utm_medium=sponsor_banner&utm_campaign=feb_march#openings
title: https://striveworks.us/careers
img: https://fastapi.tiangolo.com/img/sponsors/striveworks.png

View File

@@ -0,0 +1,10 @@
logins:
- jina-ai
- deta
- investsuite
- mikeckennedy
- deepset-ai
- cryptapi
- Striveworks
- xoflare
- InesIvanova

View File

@@ -1,3 +1,5 @@
# Additional Responses in OpenAPI
!!! warning
This is a rather advanced topic.
@@ -21,8 +23,8 @@ 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"
{!./src/additional_responses/tutorial001.py!}
```Python hl_lines="18 23"
{!../../../docs_src/additional_responses/tutorial001.py!}
```
!!! note
@@ -42,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": {
@@ -81,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": {
@@ -166,8 +168,8 @@ 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"
{!./src/additional_responses/tutorial002.py!}
```Python hl_lines="19-24 28"
{!../../../docs_src/additional_responses/tutorial002.py!}
```
!!! note
@@ -190,8 +192,8 @@ 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"
{!./src/additional_responses/tutorial003.py!}
```Python hl_lines="20-31"
{!../../../docs_src/additional_responses/tutorial003.py!}
```
It will all be combined and included in your OpenAPI, and shown in the API docs:
@@ -226,8 +228,8 @@ 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"
{!./src/additional_responses/tutorial004.py!}
```Python hl_lines="13-17 26"
{!../../../docs_src/additional_responses/tutorial004.py!}
```
## More information about OpenAPI responses

View File

@@ -1,4 +1,6 @@
By default, **FastAPI** will return the responses using Starlette's `JSONResponse`, putting the content you return from your *path operation* inside of that `JSONResponse`.
# Additional Status Codes
By default, **FastAPI** will return the responses using a `JSONResponse`, putting the content you return from your *path operation* inside of that `JSONResponse`.
It will use the default status code or the one you set in your *path operation*.
@@ -12,8 +14,8 @@ 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 20"
{!./src/additional_status_codes/tutorial001.py!}
```Python hl_lines="4 23"
{!../../../docs_src/additional_status_codes/tutorial001.py!}
```
!!! warning
@@ -23,8 +25,13 @@ To achieve that, import `JSONResponse`, and return your content there directly,
Make sure it has the data you want it to have, and that the values are valid JSON (if you are using `JSONResponse`).
!!! note "Technical Details"
You could also use `from starlette.responses import JSONResponse`.
**FastAPI** provides the same `starlette.responses` as `fastapi.responses` just as a convenience for you, the developer. But most of the available responses come directly from Starlette. The same with `status`.
## OpenAPI and API docs
If you return additional status codes and responses directly, they won't be included in the OpenAPI schema (the API docs), because FastAPI doesn't have a way to know before hand what you are going to return.
If you return additional status codes and responses directly, they won't be included in the OpenAPI schema (the API docs), because FastAPI doesn't have a way to know beforehand what you are going to return.
But you can document that in your code, using: [Additional Responses](additional-responses.md){.internal-link target=_blank}.

View File

@@ -1,7 +1,4 @@
!!! warning
This is, more or less, an "advanced" chapter.
If you are just starting with **FastAPI** you might want to skip this chapter and come back to it later.
# Advanced Dependencies
## Parameterized dependencies
@@ -22,7 +19,7 @@ Not the class itself (which is already a callable), but an instance of that clas
To do that, we declare a method `__call__`:
```Python hl_lines="10"
{!./src/dependencies/tutorial011.py!}
{!../../../docs_src/dependencies/tutorial011.py!}
```
In this case, this `__call__` is what **FastAPI** will use to check for additional parameters and sub-dependencies, and this is what will be called to pass a value to the parameter in your *path operation function* later.
@@ -32,7 +29,7 @@ In this case, this `__call__` is what **FastAPI** will use to check for addition
And now, we can use `__init__` to declare the parameters of the instance that we can use to "parameterize" the dependency:
```Python hl_lines="7"
{!./src/dependencies/tutorial011.py!}
{!../../../docs_src/dependencies/tutorial011.py!}
```
In this case, **FastAPI** won't ever touch or care about `__init__`, we will use it directly in our code.
@@ -42,7 +39,7 @@ In this case, **FastAPI** won't ever touch or care about `__init__`, we will use
We could create an instance of this class with:
```Python hl_lines="16"
{!./src/dependencies/tutorial011.py!}
{!../../../docs_src/dependencies/tutorial011.py!}
```
And that way we are able to "parameterize" our dependency, that now has `"bar"` inside of it, as the attribute `checker.fixed_content`.
@@ -60,7 +57,7 @@ checker(q="somequery")
...and pass whatever that returns as the value of the dependency in our *path operation function* as the parameter `fixed_content_included`:
```Python hl_lines="20"
{!./src/dependencies/tutorial011.py!}
{!../../../docs_src/dependencies/tutorial011.py!}
```
!!! tip

View File

@@ -1,3 +1,5 @@
# Async SQL (Relational) Databases
You can also use <a href="https://github.com/encode/databases" class="external-link" target="_blank">`encode/databases`</a> with **FastAPI** to connect to databases using `async` and `await`.
It is compatible with:
@@ -21,8 +23,8 @@ 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"
{!./src/async_sql_databases/tutorial001.py!}
```Python hl_lines="4 14 16-22"
{!../../../docs_src/async_sql_databases/tutorial001.py!}
```
!!! tip
@@ -36,8 +38,8 @@ 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"
{!./src/async_sql_databases/tutorial001.py!}
```Python hl_lines="3 9 12"
{!../../../docs_src/async_sql_databases/tutorial001.py!}
```
!!! tip
@@ -52,8 +54,8 @@ 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"
{!./src/async_sql_databases/tutorial001.py!}
```Python hl_lines="25-28"
{!../../../docs_src/async_sql_databases/tutorial001.py!}
```
## Create models
@@ -63,8 +65,8 @@ Create Pydantic models for:
* Notes to be created (`NoteIn`).
* Notes to be returned (`Note`).
```Python hl_lines="31 32 33 36 37 38 39"
{!./src/async_sql_databases/tutorial001.py!}
```Python hl_lines="31-33 36-39"
{!../../../docs_src/async_sql_databases/tutorial001.py!}
```
By creating these Pydantic models, the input data will be validated, serialized (converted), and annotated (documented).
@@ -76,16 +78,16 @@ 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"
{!./src/async_sql_databases/tutorial001.py!}
```Python hl_lines="42 45-47 50-52"
{!../../../docs_src/async_sql_databases/tutorial001.py!}
```
## Read notes
Create the *path operation function* to read notes:
```Python hl_lines="55 56 57 58"
{!./src/async_sql_databases/tutorial001.py!}
```Python hl_lines="55-58"
{!../../../docs_src/async_sql_databases/tutorial001.py!}
```
!!! Note
@@ -101,8 +103,8 @@ 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"
{!./src/async_sql_databases/tutorial001.py!}
```Python hl_lines="61-65"
{!../../../docs_src/async_sql_databases/tutorial001.py!}
```
!!! Note

View File

@@ -0,0 +1,88 @@
# 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.mark.anyio
If we want to call asynchronous functions in our tests, our test functions have to be asynchronous. Anyio provides a neat plugin for this, that allows us to specify that some test functions are to be called asynchronously.
## 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.anyio` 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>) Remember to instantiate objects that need an event loop only within async functions, e.g. an `'@app.on_event("startup")` callback.

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

@@ -0,0 +1,58 @@
# Conditional OpenAPI
If you needed to, you could use settings and environment variables to configure OpenAPI conditionally depending on the environment, and even disable it entirely.
## About security, APIs, and docs
Hiding your documentation user interfaces in production *shouldn't* be the way to protect your API.
That doesn't add any extra security to your API, the *path operations* will still be available where they are.
If there's a security flaw in your code, it will still exist.
Hiding the documentation just makes it more difficult to understand how to interact with your API, and could make it more difficult for you to debug it in production. It could be considered simply a form of <a href="https://en.wikipedia.org/wiki/Security_through_obscurity" class="external-link" target="_blank">Security through obscurity</a>.
If you want to secure your API, there are several better things you can do, for example:
* Make sure you have well defined Pydantic models for your request bodies and responses.
* Configure any required permissions and roles using dependencies.
* Never store plaintext passwords, only password hashes.
* Implement and use well-known cryptographic tools, like Passlib and JWT tokens, etc.
* Add more granular permission controls with OAuth2 scopes where needed.
* ...etc.
Nevertheless, you might have a very specific use case where you really need to disable the API docs for some environment (e.g. for production) or depending on configurations from environment variables.
## Conditional OpenAPI from settings and env vars
You can easily use the same Pydantic settings to configure your generated OpenAPI and the docs UIs.
For example:
```Python hl_lines="6 11"
{!../../../docs_src/conditional_openapi/tutorial001.py!}
```
Here we declare the setting `openapi_url` with the same default of `"/openapi.json"`.
And then we use it when creating the `FastAPI` app.
Then you could disable OpenAPI (including the UI docs) by setting the environment variable `OPENAPI_URL` to the empty string, like:
<div class="termy">
```console
$ OPENAPI_URL= uvicorn main:app
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
Then if you go to the URLs at `/openapi.json`, `/docs`, or `/redoc` you will just get a `404 Not Found` error like:
```JSON
{
"detail": "Not Found"
}
```

View File

@@ -1,3 +1,5 @@
# Custom Request and APIRoute class
In some cases, you may want to override the logic used by the `Request` and `APIRoute` classes.
In particular, this may be a good alternative to logic in a middleware.
@@ -25,14 +27,17 @@ And an `APIRoute` subclass to use that custom request class.
### Create a custom `GzipRequest` class
!!! tip
This is a toy example to demonstrate how it works, if you need Gzip support, you can use the provided [`GzipMiddleware`](./middleware.md#gzipmiddleware){.internal-link target=_blank}.
First, we create a `GzipRequest` class, which will overwrite the `Request.body()` method to decompress the body in the presence of an appropriate header.
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="10 11 12 13 14 15 16 17"
{!./src/custom_request_and_route/tutorial001.py!}
```Python hl_lines="8-15"
{!../../../docs_src/custom_request_and_route/tutorial001.py!}
```
### Create a custom `GzipRoute` class
@@ -45,8 +50,8 @@ 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="20 21 22 23 24 25 26 27 28"
{!./src/custom_request_and_route/tutorial001.py!}
```Python hl_lines="18-26"
{!../../../docs_src/custom_request_and_route/tutorial001.py!}
```
!!! note "Technical Details"
@@ -79,26 +84,26 @@ 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="15 17"
{!./src/custom_request_and_route/tutorial002.py!}
```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="18 19 20"
{!./src/custom_request_and_route/tutorial002.py!}
```Python hl_lines="16-18"
{!../../../docs_src/custom_request_and_route/tutorial002.py!}
```
## Custom `APIRoute` class in a router
You can also set the `route_class` parameter of an `APIRouter`:
```Python hl_lines="28"
{!./src/custom_request_and_route/tutorial003.py!}
```Python hl_lines="26"
{!../../../docs_src/custom_request_and_route/tutorial003.py!}
```
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="15 16 17 18 19 20 21 22"
{!./src/custom_request_and_route/tutorial003.py!}
```Python hl_lines="13-20"
{!../../../docs_src/custom_request_and_route/tutorial003.py!}
```

View File

@@ -0,0 +1,264 @@
# Custom Response - HTML, Stream, File, others
By default, **FastAPI** will return the responses using `JSONResponse`.
You can override it by returning a `Response` directly as seen in [Return a Response directly](response-directly.md){.internal-link target=_blank}.
But if you return a `Response` directly, the data won't be automatically converted, and the documentation won't be automatically generated (for example, including the specific "media type", in the HTTP header `Content-Type` as part of the generated OpenAPI).
But you can also declare the `Response` that you want to be used, in the *path operation decorator*.
The contents that you return from your *path operation function* will be put inside of that `Response`.
And if that `Response` has a JSON media type (`application/json`), like is the case with the `JSONResponse` and `UJSONResponse`, the data you return will be automatically converted (and filtered) with any Pydantic `response_model` that you declared in the *path operation decorator*.
!!! note
If you use a response class with no media type, FastAPI will expect your response to have no content, so it will not document the response format in its generated OpenAPI docs.
## Use `ORJSONResponse`
For example, if you are squeezing performance, you can install and use <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a> and set the response to be `ORJSONResponse`.
Import the `Response` class (sub-class) you want to use and declare it in the *path operation decorator*.
```Python hl_lines="2 7"
{!../../../docs_src/custom_response/tutorial001b.py!}
```
!!! info
The parameter `response_class` will also be used to define the "media type" of the response.
In this case, the HTTP header `Content-Type` will be set to `application/json`.
And it will be documented as such in OpenAPI.
!!! tip
The `ORJSONResponse` is currently only available in FastAPI, not in Starlette.
## HTML Response
To return a response with HTML directly from **FastAPI**, use `HTMLResponse`.
* Import `HTMLResponse`.
* Pass `HTMLResponse` as the parameter `response_class` of your *path operation decorator*.
```Python hl_lines="2 7"
{!../../../docs_src/custom_response/tutorial002.py!}
```
!!! info
The parameter `response_class` will also be used to define the "media type" of the response.
In this case, the HTTP header `Content-Type` will be set to `text/html`.
And it will be documented as such in OpenAPI.
### Return a `Response`
As seen in [Return a Response directly](response-directly.md){.internal-link target=_blank}, you can also override the response directly in your *path operation*, by returning it.
The same example from above, returning an `HTMLResponse`, could look like:
```Python hl_lines="2 7 19"
{!../../../docs_src/custom_response/tutorial003.py!}
```
!!! warning
A `Response` returned directly by your *path operation function* won't be documented in OpenAPI (for example, the `Content-Type` won't be documented) and won't be visible in the automatic interactive docs.
!!! info
Of course, the actual `Content-Type` header, status code, etc, will come from the `Response` object your returned.
### Document in OpenAPI and override `Response`
If you want to override the response from inside of the function but at the same time document the "media type" in OpenAPI, you can use the `response_class` parameter AND return a `Response` object.
The `response_class` will then be used only to document the OpenAPI *path operation*, but your `Response` will be used as is.
#### Return an `HTMLResponse` directly
For example, it could be something like:
```Python hl_lines="7 21 23"
{!../../../docs_src/custom_response/tutorial004.py!}
```
In this example, the function `generate_html_response()` already generates and returns a `Response` instead of returning the HTML in a `str`.
By returning the result of calling `generate_html_response()`, you are already returning a `Response` that will override the default **FastAPI** behavior.
But as you passed the `HTMLResponse` in the `response_class` too, **FastAPI** will know how to document it in OpenAPI and the interactive docs as HTML with `text/html`:
<img src="/img/tutorial/custom-response/image01.png">
## Available responses
Here are some of the available responses.
Have in mind that you can use `Response` to return anything else, or even create a custom sub-class.
!!! note "Technical Details"
You could also use `from starlette.responses import HTMLResponse`.
**FastAPI** provides the same `starlette.responses` as `fastapi.responses` just as a convenience for you, the developer. But most of the available responses come directly from Starlette.
### `Response`
The main `Response` class, all the other responses inherit from it.
You can return it directly.
It accepts the following parameters:
* `content` - A `str` or `bytes`.
* `status_code` - An `int` HTTP status code.
* `headers` - A `dict` of strings.
* `media_type` - A `str` giving the media type. E.g. `"text/html"`.
FastAPI (actually Starlette) will automatically include a Content-Length header. It will also include a Content-Type header, based on the media_type and appending a charset for text types.
```Python hl_lines="1 18"
{!../../../docs_src/response_directly/tutorial002.py!}
```
### `HTMLResponse`
Takes some text or bytes and returns an HTML response, as you read above.
### `PlainTextResponse`
Takes some text or bytes and returns an plain text response.
```Python hl_lines="2 7 9"
{!../../../docs_src/custom_response/tutorial005.py!}
```
### `JSONResponse`
Takes some data and returns an `application/json` encoded response.
This is the default response used in **FastAPI**, as you read above.
### `ORJSONResponse`
A fast alternative JSON response using <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>, as you read above.
### `UJSONResponse`
An alternative JSON response using <a href="https://github.com/ultrajson/ultrajson" class="external-link" target="_blank">`ujson`</a>.
!!! warning
`ujson` is less careful than Python's built-in implementation in how it handles some edge-cases.
```Python hl_lines="2 7"
{!../../../docs_src/custom_response/tutorial001.py!}
```
!!! tip
It's possible that `ORJSONResponse` might be a faster alternative.
### `RedirectResponse`
Returns an HTTP redirect. Uses a 307 status code (Temporary Redirect) by default.
You can return a `RedirectResponse` directly:
```Python hl_lines="2 9"
{!../../../docs_src/custom_response/tutorial006.py!}
```
---
Or you can use it in the `response_class` parameter:
```Python hl_lines="2 7 9"
{!../../../docs_src/custom_response/tutorial006b.py!}
```
If you do that, then you can return the URL directly from your *path operation* function.
In this case, the `status_code` used will be the default one for the `RedirectResponse`, which is `307`.
---
You can also use the `status_code` parameter combined with the `response_class` parameter:
```Python hl_lines="2 7 9"
{!../../../docs_src/custom_response/tutorial006c.py!}
```
### `StreamingResponse`
Takes an async generator or a normal generator/iterator and streams the response body.
```Python hl_lines="2 14"
{!../../../docs_src/custom_response/tutorial007.py!}
```
#### Using `StreamingResponse` with file-like objects
If you have a file-like object (e.g. the object returned by `open()`), you can create a generator function to iterate over that file-like object.
That way, you don't have to read it all first in memory, and you can pass that generator function to the `StreamingResponse`, and return it.
This includes many libraries to interact with cloud storage, video processing, and others.
```{ .python .annotate hl_lines="2 10-12 14" }
{!../../../docs_src/custom_response/tutorial008.py!}
```
1. This is the generator function. It's a "generator function" because it contains `yield` statements inside.
2. By using a `with` block, we make sure that the file-like object is closed after the generator function is done. So, after it finishes sending the response.
3. This `yield from` tells the function to iterate over that thing named `file_like`. And then, for each part iterated, yield that part as coming from this generator function.
So, it is a generator function that transfers the "generating" work to something else internally.
By doing it this way, we can put it in a `with` block, and that way, ensure that it is closed after finishing.
!!! tip
Notice that here as we are using standard `open()` that doesn't support `async` and `await`, we declare the path operation with normal `def`.
### `FileResponse`
Asynchronously streams a file as the response.
Takes a different set of arguments to instantiate than the other response types:
* `path` - The filepath to the file to stream.
* `headers` - Any custom headers to include, as a dictionary.
* `media_type` - A string giving the media type. If unset, the filename or path will be used to infer a media type.
* `filename` - If set, this will be included in the response `Content-Disposition`.
File responses will include appropriate `Content-Length`, `Last-Modified` and `ETag` headers.
```Python hl_lines="2 10"
{!../../../docs_src/custom_response/tutorial009.py!}
```
You can also use the `response_class` parameter:
```Python hl_lines="2 8 10"
{!../../../docs_src/custom_response/tutorial009b.py!}
```
In this case, you can return the file path directly from your *path operation* function.
## 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

@@ -0,0 +1,98 @@
# Using Dataclasses
FastAPI is built on top of **Pydantic**, and I have been showing you how to use Pydantic models to declare requests and responses.
But FastAPI also supports using <a href="https://docs.python.org/3/library/dataclasses.html" class="external-link" target="_blank">`dataclasses`</a> the same way:
```Python hl_lines="1 7-12 19-20"
{!../../../docs_src/dataclasses/tutorial001.py!}
```
This is still thanks to **Pydantic**, as it has <a href="https://pydantic-docs.helpmanual.io/usage/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">internal support for `dataclasses`</a>.
So, even with the code above that doesn't use Pydantic explicitly, FastAPI is using Pydantic to convert those standard dataclasses to Pydantic's own flavor of dataclasses.
And of course, it supports the same:
* data validation
* data serialization
* data documentation, etc.
This works the same way as with Pydantic models. And it is actually achieved in the same way underneath, using Pydantic.
!!! info
Have in mind that dataclasses can't do everything Pydantic models can do.
So, you might still need to use Pydantic models.
But if you have a bunch of dataclasses laying around, this is a nice trick to use them to power a web API using FastAPI. 🤓
## Dataclasses in `response_model`
You can also use `dataclasses` in the `response_model` parameter:
```Python hl_lines="1 7-13 19"
{!../../../docs_src/dataclasses/tutorial002.py!}
```
The dataclass will be automatically converted to a Pydantic dataclass.
This way, its schema will show up in the API docs user interface:
<img src="/img/tutorial/dataclasses/image01.png">
## Dataclasses in Nested Data Structures
You can also combine `dataclasses` with other type annotations to make nested data structures.
In some cases, you might still have to use Pydantic's version of `dataclasses`. For example, if you have errors with the automatically generated API documentation.
In that case, you can simply swap the standard `dataclasses` with `pydantic.dataclasses`, which is a drop-in replacement:
```{ .python .annotate hl_lines="1 5 8-11 14-17 23-25 28" }
{!../../../docs_src/dataclasses/tutorial003.py!}
```
1. We still import `field` from standard `dataclasses`.
2. `pydantic.dataclasses` is a drop-in replacement for `dataclasses`.
3. The `Author` dataclass includes a list of `Item` dataclasses.
4. The `Author` dataclass is used as the `response_model` parameter.
5. You can use other standard type annotations with dataclasses as the request body.
In this case, it's a list of `Item` dataclasses.
6. Here we are returning a dictionary that contains `items` which is a list of dataclasses.
FastAPI is still capable of <abbr title="converting the data to a format that can be transmitted">serializing</abbr> the data to JSON.
7. Here the `response_model` is using a type annotation of a list of `Author` dataclasses.
Again, you can combine `dataclasses` with standard type annotations.
8. Notice that this *path operation function* uses regular `def` instead of `async def`.
As always, in FastAPI you can combine `def` and `async def` as needed.
If you need a refresher about when to use which, check out the section _"In a hurry?"_ in the docs about <a href="https://fastapi.tiangolo.com/async/#in-a-hurry" target="_blank" class="internal-link">`async` and `await`</a>.
9. This *path operation function* is not returning dataclasses (although it could), but a list of dictionaries with internal data.
FastAPI will use the `response_model` parameter (that includes dataclasses) to convert the response.
You can combine `dataclasses` with other type annotations in many different combinations to form complex data structures.
Check the in-code annotation tips above to see more specific details.
## Learn More
You can also combine `dataclasses` with other Pydantic models, inherit from them, include them in your own models, etc.
To learn more, check the <a href="https://pydantic-docs.helpmanual.io/usage/dataclasses/" class="external-link" target="_blank">Pydantic docs about dataclasses</a>.
## Version
This is available since FastAPI version `0.67.0`. 🔖

View File

@@ -1,14 +1,18 @@
# Events: startup - shutdown
You can define event handlers (functions) that need to be executed before the application starts up, or when the application is shutting down.
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"`:
```Python hl_lines="8"
{!./src/events/tutorial001.py!}
{!../../../docs_src/events/tutorial001.py!}
```
In this case, the `startup` event handler function will initialize the items "database" (just a `dict`) with some values.
@@ -22,7 +26,7 @@ And your application won't start receiving requests until all the `startup` even
To add a function that should be run when the application is shutting down, declare it with the event `"shutdown"`:
```Python hl_lines="6"
{!./src/events/tutorial002.py!}
{!../../../docs_src/events/tutorial002.py!}
```
Here, the `shutdown` event handler function will write a text line `"Application shutdown"` to a file `log.txt`.
@@ -40,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

@@ -1,3 +1,5 @@
# Extending OpenAPI
!!! warning
This is a rather advanced feature. You probably can skip it.
@@ -30,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
@@ -42,24 +43,24 @@ 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"
{!./src/extending_openapi/tutorial001.py!}
```Python hl_lines="1 4 7-9"
{!../../../docs_src/extending_openapi/tutorial001.py!}
```
### Generate the OpenAPI schema
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"
{!./src/extending_openapi/tutorial001.py!}
```Python hl_lines="2 15-20"
{!../../../docs_src/extending_openapi/tutorial001.py!}
```
### Modify the OpenAPI schema
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"
{!./src/extending_openapi/tutorial001.py!}
```Python hl_lines="21-23"
{!../../../docs_src/extending_openapi/tutorial001.py!}
```
### Cache the OpenAPI schema
@@ -70,8 +71,8 @@ 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"
{!./src/extending_openapi/tutorial001.py!}
```Python hl_lines="13-14 24-25"
{!../../../docs_src/extending_openapi/tutorial001.py!}
```
### Override the method
@@ -79,7 +80,7 @@ It will be generated only once, and then the same cached schema will be used for
Now you can replace the `.openapi()` method with your new function.
```Python hl_lines="28"
{!./src/extending_openapi/tutorial001.py!}
{!../../../docs_src/extending_openapi/tutorial001.py!}
```
### Check it
@@ -151,21 +152,13 @@ After that, your file structure could look like:
└── swagger-ui.css
```
### Install `aiofiles`
Now you need to install `aiofiles`:
```bash
pip install aiofiles
```
### Serve the static files
* Import `StaticFiles` from Starlette.
* Import `StaticFiles`.
* "Mount" a `StaticFiles()` instance in a specific path.
```Python hl_lines="7 11"
{!./src/extending_openapi/tutorial002.py!}
```Python hl_lines="7 11"
{!../../../docs_src/extending_openapi/tutorial002.py!}
```
### Test the static files
@@ -199,7 +192,7 @@ The first step is to disable the automatic docs, as those use the CDN by default
To disable them, set their URLs to `None` when creating your `FastAPI` app:
```Python hl_lines="9"
{!./src/extending_openapi/tutorial002.py!}
{!../../../docs_src/extending_openapi/tutorial002.py!}
```
### Include the custom docs
@@ -216,8 +209,8 @@ 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"
{!./src/extending_openapi/tutorial002.py!}
```Python hl_lines="2-6 14-22 25-27 30-36"
{!../../../docs_src/extending_openapi/tutorial002.py!}
```
!!! tip
@@ -231,8 +224,8 @@ And similarly for ReDoc...
Now, to be able to test that everything works, create a *path operation*:
```Python hl_lines="39 40 41"
{!./src/extending_openapi/tutorial002.py!}
```Python hl_lines="39-41"
{!../../../docs_src/extending_openapi/tutorial002.py!}
```
### Test it
@@ -240,3 +233,82 @@ Now, to be able to test that everything works, create a *path operation*:
Now, you should be able to disconnect your WiFi, go to your docs at <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>, and reload the page.
And even without Internet, you would be able to see the docs for your API and interact with it.
## Configuring Swagger UI
You can configure some extra <a href="https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration" class="external-link" target="_blank">Swagger UI parameters</a>.
To configure them, pass the `swagger_ui_parameters` argument when creating the `FastAPI()` app object or to the `get_swagger_ui_html()` function.
`swagger_ui_parameters` receives a dictionary with the configurations passed to Swagger UI directly.
FastAPI converts the configurations to **JSON** to make them compatible with JavaScript, as that's what Swagger UI needs.
### Disable Syntax Highlighting
For example, you could disable syntax highlighting in Swagger UI.
Without changing the settings, syntax highlighting is enabled by default:
<img src="/img/tutorial/extending-openapi/image02.png">
But you can disable it by setting `syntaxHighlight` to `False`:
```Python hl_lines="3"
{!../../../docs_src/extending_openapi/tutorial003.py!}
```
...and then Swagger UI won't show the syntax highlighting anymore:
<img src="/img/tutorial/extending-openapi/image03.png">
### Change the Theme
The same way you could set the syntax highlighting theme with the key `"syntaxHighlight.theme"` (notice that it has a dot in the middle):
```Python hl_lines="3"
{!../../../docs_src/extending_openapi/tutorial004.py!}
```
That configuration would change the syntax highlighting color theme:
<img src="/img/tutorial/extending-openapi/image04.png">
### Change Default Swagger UI Parameters
FastAPI includes some default configuration parameters appropriate for most of the use cases.
It includes these default configurations:
```Python
{!../../../fastapi/openapi/docs.py[ln:7-13]!}
```
You can override any of them by setting a different value in the argument `swagger_ui_parameters`.
For example, to disable `deepLinking` you could pass these settings to `swagger_ui_parameters`:
```Python hl_lines="3"
{!../../../docs_src/extending_openapi/tutorial005.py!}
```
### Other Swagger UI Parameters
To see all the other possible configurations you can use, read the official <a href="https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration" class="external-link" target="_blank">docs for Swagger UI parameters</a>.
### JavaScript-only settings
Swagger UI also allows other configurations to be **JavaScript-only** objects (for example, JavaScript functions).
FastAPI also includes these JavaScript-only `presets` settings:
```JavaScript
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIBundle.SwaggerUIStandalonePreset
]
```
These are **JavaScript** objects, not strings, so you can't pass them from Python code directly.
If you need to use JavaScript-only configurations like those, you can use one of the methods above. Override all the Swagger UI *path operation* and manually write any JavaScript you need.

View File

@@ -0,0 +1,267 @@
# Generate Clients
As **FastAPI** is based on the OpenAPI specification, you get automatic compatibility with many tools, including the automatic API docs (provided by Swagger UI).
One particular advantage that is not necessarily obvious is that you can **generate clients** (sometimes called <abbr title="Software Development Kits">**SDKs**</abbr> ) for your API, for many different **programming languages**.
## OpenAPI Client Generators
There are many tools to generate clients from **OpenAPI**.
A common tool is <a href="https://openapi-generator.tech/" class="external-link" target="_blank">OpenAPI Generator</a>.
If you are building a **frontend**, a very interesting alternative is <a href="https://github.com/ferdikoomen/openapi-typescript-codegen" class="external-link" target="_blank">openapi-typescript-codegen</a>.
## Generate a TypeScript Frontend Client
Let's start with a simple FastAPI application:
=== "Python 3.6 and above"
```Python hl_lines="9-11 14-15 18 19 23"
{!> ../../../docs_src/generate_clients/tutorial001.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="7-9 12-13 16-17 21"
{!> ../../../docs_src/generate_clients/tutorial001_py39.py!}
```
Notice that the *path operations* define the models they use for request payload and response payload, using the models `Item` and `ResponseMessage`.
### API Docs
If you go to the API docs, you will see that it has the **schemas** for the data to be sent in requests and received in responses:
<img src="/img/tutorial/generate-clients/image01.png">
You can see those schemas because they were declared with the models in the app.
That information is available in the app's **OpenAPI schema**, and then shown in the API docs (by Swagger UI).
And that same information from the models that is included in OpenAPI is what can be used to **generate the client code**.
### Generate a TypeScript Client
Now that we have the app with the models, we can generate the client code for the frontend.
#### Install `openapi-typescript-codegen`
You can install `openapi-typescript-codegen` in your frontend code with:
<div class="termy">
```console
$ npm install openapi-typescript-codegen --save-dev
---> 100%
```
</div>
#### Generate Client Code
To generate the client code you can use the command line application `openapi` that would now be installed.
Because it is installed in the local project, you probably wouldn't be able to call that command directly, but you would put it on your `package.json` file.
It could look like this:
```JSON hl_lines="7"
{
"name": "frontend-app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"generate-client": "openapi --input http://localhost:8000/openapi.json --output ./src/client --client axios"
},
"author": "",
"license": "",
"devDependencies": {
"openapi-typescript-codegen": "^0.20.1",
"typescript": "^4.6.2"
}
}
```
After having that NPM `generate-client` script there, you can run it with:
<div class="termy">
```console
$ npm run generate-client
frontend-app@1.0.0 generate-client /home/user/code/frontend-app
> openapi --input http://localhost:8000/openapi.json --output ./src/client --client axios
```
</div>
That command will generate code in `./src/client` and will use `axios` (the frontend HTTP library) internally.
### Try Out the Client Code
Now you can import and use the client code, it could look like this, notice that you get autocompletion for the methods:
<img src="/img/tutorial/generate-clients/image02.png">
You will also get autocompletion for the payload to send:
<img src="/img/tutorial/generate-clients/image03.png">
!!! tip
Notice the autocompletion for `name` and `price`, that was defined in the FastAPI application, in the `Item` model.
You will have inline errors for the data that you send:
<img src="/img/tutorial/generate-clients/image04.png">
The response object will also have autocompletion:
<img src="/img/tutorial/generate-clients/image05.png">
## FastAPI App with Tags
In many cases your FastAPI app will be bigger, and you will probably use tags to separate different groups of *path operations*.
For example, you could have a section for **items** and another section for **users**, and they could be separated by tags:
=== "Python 3.6 and above"
```Python hl_lines="23 28 36"
{!> ../../../docs_src/generate_clients/tutorial002.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="21 26 34"
{!> ../../../docs_src/generate_clients/tutorial002_py39.py!}
```
### Generate a TypeScript Client with Tags
If you generate a client for a FastAPI app using tags, it will normally also separate the client code based on the tags.
This way you will be able to have things ordered and grouped correctly for the client code:
<img src="/img/tutorial/generate-clients/image06.png">
In this case you have:
* `ItemsService`
* `UsersService`
### Client Method Names
Right now the generated method names like `createItemItemsPost` don't look very clean:
```TypeScript
ItemsService.createItemItemsPost({name: "Plumbus", price: 5})
```
...that's because the client generator uses the OpenAPI internal **operation ID** for each *path operation*.
OpenAPI requires that each operation ID is unique across all the *path operations*, so FastAPI uses the **function name**, the **path**, and the **HTTP method/operation** to generate that operation ID, because that way it can make sure that the operation IDs are unique.
But I'll show you how to improve that next. 🤓
## Custom Operation IDs and Better Method Names
You can **modify** the way these operation IDs are **generated** to make them simpler and have **simpler method names** in the clients.
In this case you will have to ensure that each operation ID is **unique** in some other way.
For example, you could make sure that each *path operation* has a tag, and then generate the operation ID based on the **tag** and the *path operation* **name** (the function name).
### Custom Generate Unique ID Function
FastAPI uses a **unique ID** for each *path operation*, it is used for the **operation ID** and also for the names of any needed custom models, for requests or responses.
You can customize that function. It takes an `APIRoute` and outputs a string.
For example, here it is using the first tag (you will probably have only one tag) and the *path operation* name (the function name).
You can then pass that custom function to **FastAPI** as the `generate_unique_id_function` parameter:
=== "Python 3.6 and above"
```Python hl_lines="8-9 12"
{!> ../../../docs_src/generate_clients/tutorial003.py!}
```
=== "Python 3.9 and above"
```Python hl_lines="6-7 10"
{!> ../../../docs_src/generate_clients/tutorial003_py39.py!}
```
### Generate a TypeScript Client with Custom Operation IDs
Now if you generate the client again, you will see that it has the improved method names:
<img src="/img/tutorial/generate-clients/image07.png">
As you see, the method names now have the tag and then the function name, now they don't include information from the URL path and the HTTP operation.
### Preprocess the OpenAPI Specification for the Client Generator
The generated code still has some **duplicated information**.
We already know that this method is related to the **items** because that word is in the `ItemsService` (taken from the tag), but we still have the tag name prefixed in the method name too. 😕
We will probably still want to keep it for OpenAPI in general, as that will ensure that the operation IDs are **unique**.
But for the generated client we could **modify** the OpenAPI operation IDs right before generating the clients, just to make those method names nicer and **cleaner**.
We could download the OpenAPI JSON to a file `openapi.json` and then we could **remove that prefixed tag** with a script like this:
```Python
{!../../../docs_src/generate_clients/tutorial004.py!}
```
With that, the operation IDs would be renamed from things like `items-get_items` to just `get_items`, that way the client generator can generate simpler method names.
### Generate a TypeScript Client with the Preprocessed OpenAPI
Now as the end result is in a file `openapi.json`, you would modify the `package.json` to use that local file, for example:
```JSON hl_lines="7"
{
"name": "frontend-app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"generate-client": "openapi --input ./openapi.json --output ./src/client --client axios"
},
"author": "",
"license": "",
"devDependencies": {
"openapi-typescript-codegen": "^0.20.1",
"typescript": "^4.6.2"
}
}
```
After generating the new client, you would now have **clean method names**, with all the **autocompletion**, **inline errors**, etc:
<img src="/img/tutorial/generate-clients/image08.png">
## Benefits
When using the automatically generated clients you would **autocompletion** for:
* Methods.
* Request payloads in the body, query parameters, etc.
* Response payloads.
You would also have **inline errors** for everything.
And whenever you update the backend code, and **regenerate** the frontend, it would have any new *path operations* available as methods, the old ones removed, and any other change would be reflected on the generated code. 🤓
This also means that if something changed it will be **reflected** on the client code automatically. And if you **build** the client it will error out if you have any **mismatch** in the data used.
So, you would **detect many errors** very early in the development cycle instead of having to wait for the errors to show up to your final users in production and then trying to debug where the problem is. ✨

View File

@@ -0,0 +1,56 @@
# GraphQL
As **FastAPI** is based on the **ASGI** standard, it's very easy to integrate any **GraphQL** library also compatible with ASGI.
You can combine normal FastAPI *path operations* with GraphQL on the same application.
!!! tip
**GraphQL** solves some very specific use cases.
It has **advantages** and **disadvantages** when compared to common **web APIs**.
Make sure you evaluate if the **benefits** for your use case compensate the **drawbacks**. 🤓
## GraphQL Libraries
Here are some of the **GraphQL** libraries that have **ASGI** support. You could use them with **FastAPI**:
* <a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry</a> 🍓
* With <a href="https://strawberry.rocks/docs/integrations/fastapi" class="external-link" target="_blank">docs for FastAPI</a>
* <a href="https://ariadnegraphql.org/" class="external-link" target="_blank">Ariadne</a>
* With <a href="https://ariadnegraphql.org/docs/starlette-integration" class="external-link" target="_blank">docs for Starlette</a> (that also apply to FastAPI)
* <a href="https://tartiflette.io/" class="external-link" target="_blank">Tartiflette</a>
* With <a href="https://tartiflette.github.io/tartiflette-asgi/" class="external-link" target="_blank">Tartiflette ASGI</a> to provide ASGI integration
* <a href="https://graphene-python.org/" class="external-link" target="_blank">Graphene</a>
* With <a href="https://github.com/ciscorn/starlette-graphene3" class="external-link" target="_blank">starlette-graphene3</a>
## GraphQL with Strawberry
If you need or want to work with **GraphQL**, <a href="https://strawberry.rocks/" class="external-link" target="_blank">**Strawberry**</a> is the **recommended** library as it has the design closest to **FastAPI's** design, it's all based on **type annotations**.
Depending on your use case, you might prefer to use a different library, but if you asked me, I would probably suggest you try **Strawberry**.
Here's a small preview of how you could integrate Strawberry with FastAPI:
```Python hl_lines="3 22 25-26"
{!../../../docs_src/graphql/tutorial001.py!}
```
You can learn more about Strawberry in the <a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry documentation</a>.
And also the docs about <a href="https://strawberry.rocks/docs/integrations/fastapi" class="external-link" target="_blank">Strawberry with FastAPI</a>.
## Older `GraphQLApp` from Starlette
Previous versions of Starlette included a `GraphQLApp` class to integrate with <a href="https://graphene-python.org/" class="external-link" target="_blank">Graphene</a>.
It was deprecated from Starlette, but if you have code that used it, you can easily **migrate** to <a href="https://github.com/ciscorn/starlette-graphene3" class="external-link" target="_blank">starlette-graphene3</a>, that covers the same use case and has an **almost identical interface**.
!!! tip
If you need GraphQL, I still would recommend you check out <a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry</a>, as it's based on type annotations instead of custom classes and types.
## Learn More
You can learn more about **GraphQL** in the <a href="https://graphql.org/" class="external-link" target="_blank">official GraphQL documentation</a>.
You can also read more about each those libraries described above in their links.

View File

@@ -1,3 +1,5 @@
# Advanced User Guide - Intro
## Additional Features
The main [Tutorial - User Guide](../tutorial/){.internal-link target=_blank} should be enough to give you a tour through all the main features of **FastAPI**.
@@ -14,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

@@ -0,0 +1,99 @@
# Advanced Middleware
In the main tutorial you read how to add [Custom Middleware](../tutorial/middleware.md){.internal-link target=_blank} to your application.
And then you also read how to handle [CORS with the `CORSMiddleware`](../tutorial/cors.md){.internal-link target=_blank}.
In this section we'll see how to use other middlewares.
## Adding ASGI middlewares
As **FastAPI** is based on Starlette and implements the <abbr title="Asynchronous Server Gateway Interface">ASGI</abbr> specification, you can use any ASGI middleware.
A middleware doesn't have to be made for FastAPI or Starlette to work, as long as it follows the ASGI spec.
In general, ASGI middlewares are classes that expect to receive an ASGI app as the first argument.
So, in the documentation for third-party ASGI middlewares they will probably tell you to do something like:
```Python
from unicorn import UnicornMiddleware
app = SomeASGIApp()
new_app = UnicornMiddleware(app, some_config="rainbow")
```
But FastAPI (actually Starlette) provides a simpler way to do it that makes sure that the internal middlewares to handle server errors and custom exception handlers work properly.
For that, you use `app.add_middleware()` (as in the example for CORS).
```Python
from fastapi import FastAPI
from unicorn import UnicornMiddleware
app = FastAPI()
app.add_middleware(UnicornMiddleware, some_config="rainbow")
```
`app.add_middleware()` receives a middleware class as the first argument and any additional arguments to be passed to the middleware.
## Integrated middlewares
**FastAPI** includes several middlewares for common use cases, we'll see next how to use them.
!!! note "Technical Details"
For the next examples, you could also use `from starlette.middleware.something import SomethingMiddleware`.
**FastAPI** provides several middlewares in `fastapi.middleware` just as a convenience for you, the developer. But most of the available middlewares come directly from Starlette.
## `HTTPSRedirectMiddleware`
Enforces that all incoming requests must either be `https` or `wss`.
Any incoming requests to `http` or `ws` will be redirected to the secure scheme instead.
```Python hl_lines="2 6"
{!../../../docs_src/advanced_middleware/tutorial001.py!}
```
## `TrustedHostMiddleware`
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-8"
{!../../../docs_src/advanced_middleware/tutorial002.py!}
```
The following arguments are supported:
* `allowed_hosts` - A list of domain names that should be allowed as hostnames. Wildcard domains such as `*.example.com` are supported for matching subdomains to allow any hostname either use `allowed_hosts=["*"]` or omit the middleware.
If an incoming request does not validate correctly then a `400` response will be sent.
## `GZipMiddleware`
Handles GZip responses for any request that includes `"gzip"` in the `Accept-Encoding` header.
The middleware will handle both standard and streaming responses.
```Python hl_lines="2 6"
{!../../../docs_src/advanced_middleware/tutorial003.py!}
```
The following arguments are supported:
* `minimum_size` - Do not GZip responses that are smaller than this minimum size in bytes. Defaults to `500`.
## Other middlewares
There are many other ASGI middlewares.
For example:
* <a href="https://docs.sentry.io/platforms/python/asgi/" class="external-link" target="_blank">Sentry</a>
* <a href="https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py" class="external-link" target="_blank">Uvicorn's `ProxyHeadersMiddleware`</a>
* <a href="https://github.com/florimondmanca/msgpack-asgi" class="external-link" target="_blank">MessagePack</a>
To see other available middlewares check <a href="https://www.starlette.io/middleware/" class="external-link" target="_blank">Starlette's Middleware docs</a> and the <a href="https://github.com/florimondmanca/awesome-asgi" class="external-link" target="_blank">ASGI Awesome List</a>.

View File

@@ -1,3 +1,5 @@
# NoSQL (Distributed / Big Data) Databases
**FastAPI** can also be integrated with any <abbr title="Distributed database (Big Data), also 'Not Only SQL'">NoSQL</abbr>.
Here we'll see an example using **<a href="https://www.couchbase.com/" class="external-link" target="_blank">Couchbase</a>**, a <abbr title="Document here refers to a JSON object (a dict), with keys and values, and those values can also be other JSON objects, arrays (lists), numbers, strings, booleans, etc.">document</abbr> based NoSQL database.
@@ -17,8 +19,8 @@ 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"
{!./src/nosql_databases/tutorial001.py!}
```Python hl_lines="3-5"
{!../../../docs_src/nosql_databases/tutorial001.py!}
```
## Define a constant to use as a "document type"
@@ -27,8 +29,8 @@ 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"
{!./src/nosql_databases/tutorial001.py!}
```Python hl_lines="9"
{!../../../docs_src/nosql_databases/tutorial001.py!}
```
## Add a function to get a `Bucket`
@@ -52,8 +54,8 @@ This utility function will:
* Set defaults for timeouts.
* Return it.
```Python hl_lines="13 14 15 16 17 18 19 20 21 22"
{!./src/nosql_databases/tutorial001.py!}
```Python hl_lines="12-21"
{!../../../docs_src/nosql_databases/tutorial001.py!}
```
## Create Pydantic models
@@ -64,8 +66,8 @@ 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"
{!./src/nosql_databases/tutorial001.py!}
```Python hl_lines="24-28"
{!../../../docs_src/nosql_databases/tutorial001.py!}
```
We will use this model in our *path operation function*, so, we don't include in it the `hashed_password`.
@@ -78,8 +80,8 @@ 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"
{!./src/nosql_databases/tutorial001.py!}
```Python hl_lines="31-33"
{!../../../docs_src/nosql_databases/tutorial001.py!}
```
!!! note
@@ -98,8 +100,8 @@ 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"
{!./src/nosql_databases/tutorial001.py!}
```Python hl_lines="36-42"
{!../../../docs_src/nosql_databases/tutorial001.py!}
```
### f-strings
@@ -133,18 +135,18 @@ UserInDB(username="johndoe", hashed_password="some_hash")
### Create the `FastAPI` app
```Python hl_lines="47"
{!./src/nosql_databases/tutorial001.py!}
```Python hl_lines="46"
{!../../../docs_src/nosql_databases/tutorial001.py!}
```
### Create the *path operation function*
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"
{!./src/nosql_databases/tutorial001.py!}
```Python hl_lines="49-53"
{!../../../docs_src/nosql_databases/tutorial001.py!}
```
## Recap

View File

@@ -1,3 +1,5 @@
# OpenAPI Callbacks
You could create an API with a *path operation* that could trigger a request to an *external API* created by someone else (probably the same developer that would be *using* your API).
The process that happens when your API app calls the *external API* is named a "callback". Because the software that the external developer wrote sends a request to your API and then your API *calls back*, sending a request to an *external API* (that was probably created by the same developer).
@@ -29,8 +31,8 @@ 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"
{!./src/openapi_callbacks/tutorial001.py!}
```Python hl_lines="10-14 37-54"
{!../../../docs_src/openapi_callbacks/tutorial001.py!}
```
!!! tip
@@ -81,17 +83,8 @@ So we are going to use that same knowledge to document how the *external API* sh
First create a new `APIRouter` that will contain one or more callbacks.
This router will never be added to an actual `FastAPI` app (i.e. it will never be passed to `app.include_router(...)`).
Because of that, you need to declare what will be the `default_response_class`, and set it to `JSONResponse`.
!!! Note "Technical Details"
The `response_class` is normally set by the `FastAPI` app during the call to `app.include_router(some_router)`.
But as we are never calling `app.include_router(some_router)`, we need to set the `default_response_class` during creation of the `APIRouter`.
```Python hl_lines="3 24"
{!./src/openapi_callbacks/tutorial001.py!}
```Python hl_lines="5 26"
{!../../../docs_src/openapi_callbacks/tutorial001.py!}
```
### Create the callback *path operation*
@@ -103,8 +96,8 @@ 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"
{!./src/openapi_callbacks/tutorial001.py!}
```Python hl_lines="17-19 22-23 29-33"
{!../../../docs_src/openapi_callbacks/tutorial001.py!}
```
There are 2 main differences from a normal *path operation*:
@@ -170,8 +163,8 @@ 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"
{!./src/openapi_callbacks/tutorial001.py!}
```Python hl_lines="36"
{!../../../docs_src/openapi_callbacks/tutorial001.py!}
```
!!! tip

View File

@@ -0,0 +1,170 @@
# Path Operation Advanced Configuration
## OpenAPI operationId
!!! warning
If you are not an "expert" in OpenAPI, you probably don't need this.
You can set the OpenAPI `operationId` to be used in your *path operation* with the parameter `operation_id`.
You would have to make sure that it is unique for each operation.
```Python hl_lines="6"
{!../../../docs_src/path_operation_advanced_configuration/tutorial001.py!}
```
### Using the *path operation function* name as the operationId
If you want to use your APIs' function names as `operationId`s, you can iterate over all of them and override each *path operation's* `operation_id` using their `APIRoute.name`.
You should do it after adding all your *path operations*.
```Python hl_lines="2 12-21 24"
{!../../../docs_src/path_operation_advanced_configuration/tutorial002.py!}
```
!!! tip
If you manually call `app.openapi()`, you should update the `operationId`s before that.
!!! warning
If you do this, you have to make sure each one of your *path operation functions* has a unique name.
Even if they are in different modules (Python files).
## Exclude from OpenAPI
To exclude a *path operation* from the generated OpenAPI schema (and thus, from the automatic documentation systems), use the parameter `include_in_schema` and set it to `False`:
```Python hl_lines="6"
{!../../../docs_src/path_operation_advanced_configuration/tutorial003.py!}
```
## Advanced description from docstring
You can limit the lines used from the docstring of a *path operation function* for OpenAPI.
Adding an `\f` (an escaped "form feed" character) causes **FastAPI** to truncate the output used for OpenAPI at this point.
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-29"
{!../../../docs_src/path_operation_advanced_configuration/tutorial004.py!}
```
## Additional Responses
You probably have seen how to declare the `response_model` and `status_code` for a *path operation*.
That defines the metadata about the main response of a *path operation*.
You can also declare additional responses with their models, status codes, etc.
There's a whole chapter here in the documentation about it, you can read it at [Additional Responses in OpenAPI](./additional-responses.md){.internal-link target=_blank}.
## OpenAPI Extra
When you declare a *path operation* in your application, **FastAPI** automatically generates the relevant metadata about that *path operation* to be included in the OpenAPI schema.
!!! note "Technical details"
In the OpenAPI specification it is called the <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object" class="external-link" target="_blank">Operation Object</a>.
It has all the information about the *path operation* and is used to generate the automatic documentation.
It includes the `tags`, `parameters`, `requestBody`, `responses`, etc.
This *path operation*-specific OpenAPI schema is normally generated automatically by **FastAPI**, but you can also extend it.
!!! tip
This is a low level extension point.
If you only need to declare additional responses, a more convenient way to do it is with [Additional Responses in OpenAPI](./additional-responses.md){.internal-link target=_blank}.
You can extend the OpenAPI schema for a *path operation* using the parameter `openapi_extra`.
### OpenAPI Extensions
This `openapi_extra` can be helpful, for example, to declare [OpenAPI Extensions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions):
```Python hl_lines="6"
{!../../../docs_src/path_operation_advanced_configuration/tutorial005.py!}
```
If you open the automatic API docs, your extension will show up at the bottom of the specific *path operation*.
<img src="/img/tutorial/path-operation-advanced-configuration/image01.png">
And if you see the resulting OpenAPI (at `/openapi.json` in your API), you will see your extension as part of the specific *path operation* too:
```JSON hl_lines="22"
{
"openapi": "3.0.2",
"info": {
"title": "FastAPI",
"version": "0.1.0"
},
"paths": {
"/items/": {
"get": {
"summary": "Read Items",
"operationId": "read_items_items__get",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {}
}
}
}
},
"x-aperture-labs-portal": "blue"
}
}
}
}
```
### Custom OpenAPI *path operation* schema
The dictionary in `openapi_extra` will be deeply merged with the automatically generated OpenAPI schema for the *path operation*.
So, you could add additional data to the automatically generated schema.
For example, you could decide to read and validate the request with your own code, without using the automatic features of FastAPI with Pydantic, but you could still want to define the request in the OpenAPI schema.
You could do that with `openapi_extra`:
```Python hl_lines="20-37 39-40"
{!../../../docs_src/path_operation_advanced_configuration/tutorial006.py!}
```
In this example, we didn't declare any Pydantic model. In fact, the request body is not even <abbr title="converted from some plain format, like bytes, into Python objects">parsed</abbr> as JSON, it is read directly as `bytes`, and the function `magic_data_reader()` would be in charge of parsing it in some way.
Nevertheless, we can declare the expected schema for the request body.
### Custom OpenAPI content type
Using this same trick, you could use a Pydantic model to define the JSON Schema that is then included in the custom OpenAPI schema section for the *path operation*.
And you could do this even if the data type in the request is not JSON.
For example, in this application we don't use FastAPI's integrated functionality to extract the JSON Schema from Pydantic models nor the automatic validation for JSON. In fact, we are declaring the request content type as YAML, not JSON:
```Python hl_lines="17-22 24"
{!../../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
```
Nevertheless, although we are not using the default integrated functionality, we are still using a Pydantic model to manually generate the JSON Schema for the data that we want to receive in YAML.
Then we use the request directly, and extract the body as `bytes`. This means that FastAPI won't even try to parse the request payload as JSON.
And then in our code, we parse that YAML content directly, and then we are again using the same Pydantic model to validate the YAML content:
```Python hl_lines="26-33"
{!../../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
```
!!! tip
Here we re-use the same Pydantic model.
But the same way, we could have validated it in some other way.

View File

@@ -1,3 +1,5 @@
# Response - Change Status Code
You probably read before that you can set a default [Response Status Code](../tutorial/response-status-code.md){.internal-link target=_blank}.
But in some cases you need to return a different status code than the default.
@@ -18,8 +20,8 @@ You can declare a parameter of type `Response` in your *path operation function*
And then you can set the `status_code` in that *temporal* response object.
```Python hl_lines="2 11 14"
{!./src/response_change_status_code/tutorial001.py!}
```Python hl_lines="1 9 12"
{!../../../docs_src/response_change_status_code/tutorial001.py!}
```
And then you can return any object you need, as you normally would (a `dict`, a database model, etc).

View File

@@ -1,11 +1,13 @@
# Response Cookies
## Use a `Response` parameter
You can declare a parameter of type `Response` in your *path operation function*.
And then you can set headers in that *temporal* response object.
And then you can set cookies in that *temporal* response object.
```Python hl_lines="2 8 9"
{!./src/response_cookies/tutorial002.py!}
```Python hl_lines="1 8-9"
{!../../../docs_src/response_cookies/tutorial002.py!}
```
And then you can return any object you need, as you normally would (a `dict`, a database model, etc).
@@ -24,8 +26,8 @@ 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"
{!./src/response_cookies/tutorial001.py!}
```Python hl_lines="10-12"
{!../../../docs_src/response_cookies/tutorial001.py!}
```
!!! tip
@@ -37,4 +39,11 @@ Then set Cookies in it, and then return it:
### More info
!!! note "Technical Details"
You could also use `from starlette.responses import Response` or `from starlette.responses import JSONResponse`.
**FastAPI** provides the same `starlette.responses` as `fastapi.responses` just as a convenience for you, the developer. But most of the available responses come directly from Starlette.
And as the `Response` can be used frequently to set headers and cookies, **FastAPI** also provides it at `fastapi.Response`.
To see all the available parameters and options, check the <a href="https://www.starlette.io/responses/#set-cookie" class="external-link" target="_blank">documentation in Starlette</a>.

View File

@@ -1,21 +1,23 @@
# Return a Response Directly
When you create a **FastAPI** *path operation* you can normally return any data from it: a `dict`, a `list`, a Pydantic model, a database model, etc.
By default, **FastAPI** would automatically convert that return value to JSON using the `jsonable_encoder` explained in [JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank}.
Then, behind the scenes, it would put that JSON-compatible data (e.g. a `dict`) inside of a Starlette `JSONResponse` that would be used to send the response to the client.
Then, behind the scenes, it would put that JSON-compatible data (e.g. a `dict`) inside of a `JSONResponse` that would be used to send the response to the client.
But you can return a `JSONResponse` directly from your *path operations*.
It might be useful, for example, to return custom headers or cookies.
## Starlette `Response`
## Return a `Response`
In fact, you can return any <a href="https://www.starlette.io/responses/" class="external-link" target="_blank">Starlette `Response`</a> or any sub-class of it.
In fact, you can return any `Response` or any sub-class of it.
!!! tip
`JSONResponse` itself is a sub-class of `Response`.
And when you return a Starlette `Response`, **FastAPI** will pass it directly.
And when you return a `Response`, **FastAPI** will pass it directly.
It won't do any data conversion with Pydantic models, it won't convert the contents to any type, etc.
@@ -29,12 +31,14 @@ 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"
{!./src/response_directly/tutorial001.py!}
```Python hl_lines="6-7 21-22"
{!../../../docs_src/response_directly/tutorial001.py!}
```
!!! note
Notice that you import it directly from `starlette.responses`, not from `fastapi`.
!!! note "Technical Details"
You could also use `from starlette.responses import JSONResponse`.
**FastAPI** provides the same `starlette.responses` as `fastapi.responses` just as a convenience for you, the developer. But most of the available responses come directly from Starlette.
## Returning a custom `Response`
@@ -42,14 +46,12 @@ The example above shows all the parts you need, but it's not very useful yet, as
Now, let's see how you could use that to return a custom response.
Let's say you want to return a response that is not available in the default <a href="https://www.starlette.io/responses/" class="external-link" target="_blank">Starlette `Response`s</a>.
Let's say that you want to return an <a href="https://en.wikipedia.org/wiki/XML" class="external-link" target="_blank">XML</a> response.
Let's say that you want to return <a href="https://en.wikipedia.org/wiki/XML" class="external-link" target="_blank">XML</a>.
You could put your XML content in a string, put it in a `Response`, and return it:
You could put your XML content in a string, put it in a Starlette Response, and return it:
```Python hl_lines="2 20"
{!./src/response_directly/tutorial002.py!}
```Python hl_lines="1 18"
{!../../../docs_src/response_directly/tutorial002.py!}
```
## Notes

View File

@@ -1,11 +1,13 @@
# Response Headers
## Use a `Response` parameter
You can declare a parameter of type `Response` in your *path operation function* (as you can do for cookies).
And then you can set headers in that *temporal* response object.
```Python hl_lines="2 8 9"
{!./src/response_headers/tutorial002.py!}
```Python hl_lines="1 7-8"
{!../../../docs_src/response_headers/tutorial002.py!}
```
And then you can return any object you need, as you normally would (a `dict`, a database model, etc).
@@ -22,10 +24,17 @@ 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"
{!./src/response_headers/tutorial001.py!}
```Python hl_lines="10-12"
{!../../../docs_src/response_headers/tutorial001.py!}
```
!!! note "Technical Details"
You could also use `from starlette.responses import Response` or `from starlette.responses import JSONResponse`.
**FastAPI** provides the same `starlette.responses` as `fastapi.responses` just as a convenience for you, the developer. But most of the available responses come directly from Starlette.
And as the `Response` can be used frequently to set headers and cookies, **FastAPI** also provides it at `fastapi.Response`.
## Custom Headers
Have in mind that custom proprietary headers can be added <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">using the 'X-' prefix</a>.

View File

@@ -1,3 +1,5 @@
# HTTP Basic Auth
For the simplest cases, you can use HTTP Basic Auth.
In HTTP Basic Auth, the application expects a header that contains a username and a password.
@@ -18,8 +20,8 @@ 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"
{!./src/security/tutorial006.py!}
```Python hl_lines="2 6 10"
{!../../../docs_src/security/tutorial006.py!}
```
When you try to open the URL for the first time (or click the "Execute" button in the docs) the browser will ask you for your username and password:
@@ -34,8 +36,8 @@ 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 13 14 15"
{!./src/security/tutorial007.py!}
```Python hl_lines="1 11-13"
{!../../../docs_src/security/tutorial007.py!}
```
This will ensure that `credentials.username` is `"stanleyjobson"`, and that `credentials.password` is `"swordfish"`. This would be similar to:
@@ -52,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:
@@ -65,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:
@@ -76,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()`
@@ -100,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="16 17 18 19 20"
{!./src/security/tutorial007.py!}
```Python hl_lines="15-19"
{!../../../docs_src/security/tutorial007.py!}
```

View File

@@ -1,3 +1,5 @@
# Advanced Security - Intro
## Additional Features
There are some extra features to handle security apart from the ones covered in the [Tutorial - User Guide: Security](../../tutorial/security/){.internal-link target=_blank}.

View File

@@ -1,3 +1,5 @@
# OAuth2 scopes
You can use OAuth2 scopes directly with **FastAPI**, they are integrated to work seamlessly.
This would allow you to have a more fine-grained permission system, following the OAuth2 standard, integrated into your OpenAPI application (and the API docs).
@@ -54,8 +56,8 @@ 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 48 66 107 109 110 111 112 113 114 115 116 117 123 124 125 126 130 131 132 133 134 135 136 141 155"
{!./src/security/tutorial005.py!}
```Python hl_lines="2 4 8 12 46 64 105 107-115 121-124 128-134 139 153"
{!../../../docs_src/security/tutorial005.py!}
```
Now let's review those changes step by step.
@@ -66,8 +68,8 @@ 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="64 65 66 67"
{!./src/security/tutorial005.py!}
```Python hl_lines="62-65"
{!../../../docs_src/security/tutorial005.py!}
```
Because we are now declaring those scopes, they will show up in the API docs when you log-in/authorize.
@@ -91,8 +93,8 @@ 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="156"
{!./src/security/tutorial005.py!}
```Python hl_lines="153"
{!../../../docs_src/security/tutorial005.py!}
```
## Declare scopes in *path operations* and dependencies
@@ -116,8 +118,8 @@ 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 141 168"
{!./src/security/tutorial005.py!}
```Python hl_lines="4 139 166"
{!../../../docs_src/security/tutorial005.py!}
```
!!! info "Technical Details"
@@ -141,8 +143,8 @@ 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 107"
{!./src/security/tutorial005.py!}
```Python hl_lines="8 105"
{!../../../docs_src/security/tutorial005.py!}
```
## Use the `scopes`
@@ -155,10 +157,10 @@ The `security_scopes` object (of class `SecurityScopes`) also provides a `scope_
We create an `HTTPException` that we can re-use (`raise`) later at several points.
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).
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 the `WWW-Authenticate` header (this is part of the spec).
```Python hl_lines="107 109 110 111 112 113 114 115 116 117"
{!./src/security/tutorial005.py!}
```Python hl_lines="105 107-115"
{!../../../docs_src/security/tutorial005.py!}
```
## Verify the `username` and data shape
@@ -175,8 +177,8 @@ 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="48 118 119 120 121 122 123 124 125 126 127 128 129"
{!./src/security/tutorial005.py!}
```Python hl_lines="46 116-127"
{!../../../docs_src/security/tutorial005.py!}
```
## Verify the `scopes`
@@ -185,8 +187,8 @@ 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="130 131 132 133 134 135 136"
{!./src/security/tutorial005.py!}
```Python hl_lines="128-134"
{!../../../docs_src/security/tutorial005.py!}
```
## Dependency tree and scopes

View File

@@ -0,0 +1,382 @@
# Settings and Environment Variables
In many cases your application could need some external settings or configurations, for example secret keys, database credentials, credentials for email services, etc.
Most of these settings are variable (can change), like database URLs. And many could be sensitive, like secrets.
For this reason it's common to provide them in environment variables that are read by the application.
## Environment Variables
!!! tip
If you already know what "environment variables" are and how to use them, feel free to skip to the next section below.
An <a href="https://en.wikipedia.org/wiki/Environment_variable" class="external-link" target="_blank">environment variable</a> (also known as "env var") is a variable that lives outside of the Python code, in the operating system, and could be read by your Python code (or by other programs as well).
You can create and use environment variables in the shell, without needing Python:
=== "Linux, macOS, Windows Bash"
<div class="termy">
```console
// You could create an env var MY_NAME with
$ export MY_NAME="Wade Wilson"
// Then you could use it with other programs, like
$ echo "Hello $MY_NAME"
Hello Wade Wilson
```
</div>
=== "Windows PowerShell"
<div class="termy">
```console
// Create an env var MY_NAME
$ $Env:MY_NAME = "Wade Wilson"
// Use it with other programs, like
$ echo "Hello $Env:MY_NAME"
Hello Wade Wilson
```
</div>
### Read env vars in Python
You could also create environment variables outside of Python, in the terminal (or with any other method), and then read them in Python.
For example you could have a file `main.py` with:
```Python hl_lines="3"
import os
name = os.getenv("MY_NAME", "World")
print(f"Hello {name} from Python")
```
!!! tip
The second argument to <a href="https://docs.python.org/3.8/library/os.html#os.getenv" class="external-link" target="_blank">`os.getenv()`</a> is the default value to return.
If not provided, it's `None` by default, here we provide `"World"` as the default value to use.
Then you could call that Python program:
<div class="termy">
```console
// Here we don't set the env var yet
$ python main.py
// As we didn't set the env var, we get the default value
Hello World from Python
// But if we create an environment variable first
$ export MY_NAME="Wade Wilson"
// And then call the program again
$ python main.py
// Now it can read the environment variable
Hello Wade Wilson from Python
```
</div>
As environment variables can be set outside of the code, but can be read by the code, and don't have to be stored (committed to `git`) with the rest of the files, it's common to use them for configurations or settings.
You can also create an environment variable only for a specific program invocation, that is only available to that program, and only for its duration.
To do that, create it right before the program itself, on the same line:
<div class="termy">
```console
// Create an env var MY_NAME in line for this program call
$ MY_NAME="Wade Wilson" python main.py
// Now it can read the environment variable
Hello Wade Wilson from Python
// The env var no longer exists afterwards
$ python main.py
Hello World from Python
```
</div>
!!! tip
You can read more about it at <a href="https://12factor.net/config" class="external-link" target="_blank">The Twelve-Factor App: Config</a>.
### Types and validation
These environment variables can only handle text strings, as they are external to Python and have to be compatible with other programs and the rest of the system (and even with different operating systems, as Linux, Windows, macOS).
That means that any value read in Python from an environment variable will be a `str`, and any conversion to a different type or validation has to be done in code.
## Pydantic `Settings`
Fortunately, Pydantic provides a great utility to handle these settings coming from environment variables with <a href="https://pydantic-docs.helpmanual.io/usage/settings/" class="external-link" target="_blank">Pydantic: Settings management</a>.
### Create the `Settings` object
Import `BaseSettings` from Pydantic and create a sub-class, very much like with a Pydantic model.
The same way as with Pydantic models, you declare class attributes with type annotations, and possibly default values.
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-8 11"
{!../../../docs_src/settings/tutorial001.py!}
```
!!! tip
If you want something quick to copy and paste, don't use this example, use the last one below.
Then, when you create an instance of that `Settings` class (in this case, in the `settings` object), Pydantic will read the environment variables in a case-insensitive way, so, an upper-case variable `APP_NAME` will still be read for the attribute `app_name`.
Next it will convert and validate the data. So, when you use that `settings` object, you will have data of the types you declared (e.g. `items_per_user` will be an `int`).
### Use the `settings`
Then you can use the new `settings` object in your application:
```Python hl_lines="18-20"
{!../../../docs_src/settings/tutorial001.py!}
```
### Run the server
Next, you would run the server passing the configurations as environment variables, for example you could set an `ADMIN_EMAIL` and `APP_NAME` with:
<div class="termy">
```console
$ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" uvicorn main:app
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
!!! tip
To set multiple env vars for a single command just separate them with a space, and put them all before the command.
And then the `admin_email` setting would be set to `"deadpool@example.com"`.
The `app_name` would be `"ChimichangApp"`.
And the `items_per_user` would keep its default value of `50`.
## Settings in another module
You could put those settings in another module file as you saw in [Bigger Applications - Multiple Files](../tutorial/bigger-applications.md){.internal-link target=_blank}.
For example, you could have a file `config.py` with:
```Python
{!../../../docs_src/settings/app01/config.py!}
```
And then use it in a file `main.py`:
```Python hl_lines="3 11-13"
{!../../../docs_src/settings/app01/main.py!}
```
!!! tip
You would also need a file `__init__.py` as you saw on [Bigger Applications - Multiple Files](../tutorial/bigger-applications.md){.internal-link target=_blank}.
## Settings in a dependency
In some occasions it might be useful to provide the settings from a dependency, instead of having a global object with `settings` that is used everywhere.
This could be especially useful during testing, as it's very easy to override a dependency with your own custom settings.
### The config file
Coming from the previous example, your `config.py` file could look like:
```Python hl_lines="10"
{!../../../docs_src/settings/app02/config.py!}
```
Notice that now we don't create a default instance `settings = Settings()`.
### The main app file
Now we create a dependency that returns a new `config.Settings()`.
```Python hl_lines="5 11-12"
{!../../../docs_src/settings/app02/main.py!}
```
!!! tip
We'll discuss the `@lru_cache()` in a bit.
For now you can assume `get_settings()` is a normal function.
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-20"
{!../../../docs_src/settings/app02/main.py!}
```
### Settings and testing
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="9-10 13 21"
{!../../../docs_src/settings/app02/test_main.py!}
```
In the dependency override we set a new value for the `admin_email` when creating the new `Settings` object, and then we return that new object.
Then we can test that it is used.
## Reading a `.env` file
If you have many settings that possibly change a lot, maybe in different environments, it might be useful to put them on a file and then read them from it as if they were environment variables.
This practice is common enough that it has a name, these environment variables are commonly placed in a file `.env`, and the file is called a "dotenv".
!!! tip
A file starting with a dot (`.`) is a hidden file in Unix-like systems, like Linux and macOS.
But a dotenv file doesn't really have to have that exact filename.
Pydantic has support for reading from these types of files using an external library. You can read more at <a href="https://pydantic-docs.helpmanual.io/usage/settings/#dotenv-env-support" class="external-link" target="_blank">Pydantic Settings: Dotenv (.env) support</a>.
!!! tip
For this to work, you need to `pip install python-dotenv`.
### The `.env` file
You could have a `.env` file with:
```bash
ADMIN_EMAIL="deadpool@example.com"
APP_NAME="ChimichangApp"
```
### Read settings from `.env`
And then update your `config.py` with:
```Python hl_lines="9-10"
{!../../../docs_src/settings/app03/config.py!}
```
Here we create a class `Config` inside of your Pydantic `Settings` class, and set the `env_file` to the filename with the dotenv file we want to use.
!!! tip
The `Config` class is used just for Pydantic configuration. You can read more at <a href="https://pydantic-docs.helpmanual.io/usage/model_config/" class="external-link" target="_blank">Pydantic Model Config</a>
### Creating the `Settings` only once with `lru_cache`
Reading a file from disk is normally a costly (slow) operation, so you probably want to do it only once and then re-use the same settings object, instead of reading it for each request.
But every time we do:
```Python
Settings()
```
a new `Settings` object would be created, and at creation it would read the `.env` file again.
If the dependency function was just like:
```Python
def get_settings():
return Settings()
```
we would create that object for each request, and we would be reading the `.env` file for each request. ⚠️
But as we are using the `@lru_cache()` decorator on top, the `Settings` object will be created only once, the first time it's called. ✔️
```Python hl_lines="1 10"
{!../../../docs_src/settings/app03/main.py!}
```
Then for any subsequent calls of `get_settings()` in the dependencies for the next requests, instead of executing the internal code of `get_settings()` and creating a new `Settings` object, it will return the same object that was returned on the first call, again and again.
#### `lru_cache` Technical Details
`@lru_cache()` modifies the function it decorates to return the same value that was returned the first time, instead of computing it again, executing the code of the function every time.
So, the function below it will be executed once for each combination of arguments. And then the values returned by each of those combinations of arguments will be used again and again whenever the function is called with exactly the same combination of arguments.
For example, if you have a function:
```Python
@lru_cache()
def say_hi(name: str, salutation: str = "Ms."):
return f"Hello {salutation} {name}"
```
your program could execute like this:
```mermaid
sequenceDiagram
participant code as Code
participant function as say_hi()
participant execute as Execute function
rect rgba(0, 255, 0, .1)
code ->> function: say_hi(name="Camila")
function ->> execute: execute function code
execute ->> code: return the result
end
rect rgba(0, 255, 255, .1)
code ->> function: say_hi(name="Camila")
function ->> code: return stored result
end
rect rgba(0, 255, 0, .1)
code ->> function: say_hi(name="Rick")
function ->> execute: execute function code
execute ->> code: return the result
end
rect rgba(0, 255, 0, .1)
code ->> function: say_hi(name="Rick", salutation="Mr.")
function ->> execute: execute function code
execute ->> code: return the result
end
rect rgba(0, 255, 255, .1)
code ->> function: say_hi(name="Rick")
function ->> code: return stored result
end
rect rgba(0, 255, 255, .1)
code ->> function: say_hi(name="Camila")
function ->> code: return stored result
end
```
In the case of our dependency `get_settings()`, the function doesn't even take any arguments, so it always returns the same value.
That way, it behaves almost as if it was just a global variable. But as it uses a dependency function, then we can override it easily for testing.
`@lru_cache()` is part of `functools` which is part of Python's standard library, you can read more about it in the <a href="https://docs.python.org/3/library/functools.html#functools.lru_cache" class="external-link" target="_blank">Python docs for `@lru_cache()`</a>.
## Recap
You can use Pydantic Settings to handle the settings or configurations for your application, with all the power of Pydantic models.
* By using a dependency you can simplify testing.
* You can use `.env` files with it.
* Using `@lru_cache()` lets you avoid reading the dotenv file again and again for each request, while allowing you to override it during testing.

View File

@@ -1,3 +1,5 @@
# SQL (Relational) Databases with Peewee
!!! warning
If you are just starting, the tutorial [SQL (Relational) Databases](../tutorial/sql-databases.md){.internal-link target=_blank} that uses SQLAlchemy should be enough.
@@ -5,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.
@@ -23,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
@@ -60,7 +62,7 @@ Let's refer to the file `sql_app/database.py`.
Let's first check all the normal Peewee code, create a Peewee database:
```Python hl_lines="3 5 22"
{!./src/sql_databases_peewee/sql_app/database.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/database.py!}
```
!!! tip
@@ -111,8 +113,8 @@ 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"
{!./src/sql_databases_peewee/sql_app/database.py!}
```Python hl_lines="10-19"
{!../../../docs_src/sql_databases_peewee/sql_app/database.py!}
```
This class inherits from a special internal class used by Peewee.
@@ -133,7 +135,7 @@ So, we need to do some extra tricks to make it work as if it was just using `thr
Now, overwrite the `._state` internal attribute in the Peewee database `db` object using the new `PeeweeConnectionState`:
```Python hl_lines="24"
{!./src/sql_databases_peewee/sql_app/database.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/database.py!}
```
!!! tip
@@ -159,8 +161,8 @@ 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"
{!./src/sql_databases_peewee/sql_app/models.py!}
```Python hl_lines="3 6-12 15-21"
{!../../../docs_src/sql_databases_peewee/sql_app/models.py!}
```
!!! tip
@@ -187,8 +189,8 @@ 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"
{!./src/sql_databases_peewee/sql_app/schemas.py!}
```Python hl_lines="16-18 21-22 25-30 34-35 38-39 42-48"
{!../../../docs_src/sql_databases_peewee/sql_app/schemas.py!}
```
!!! tip
@@ -212,8 +214,8 @@ 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"
{!./src/sql_databases_peewee/sql_app/schemas.py!}
```Python hl_lines="3 8-13 31 49"
{!../../../docs_src/sql_databases_peewee/sql_app/schemas.py!}
```
Here we are checking if the attribute that is being accessed (e.g. `.items` in `some_user.items`) is an instance of `peewee.ModelSelect`.
@@ -233,8 +235,8 @@ 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"
{!./src/sql_databases_peewee/sql_app/crud.py!}
```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!}
```
There are some differences with the code for the SQLAlchemy tutorial.
@@ -257,16 +259,16 @@ 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"
{!./src/sql_databases_peewee/sql_app/main.py!}
```Python hl_lines="9-11"
{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
```
### Create a dependency
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"
{!./src/sql_databases_peewee/sql_app/main.py!}
```Python hl_lines="23-29"
{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
```
Here we have an empty `yield` because we are actually not using the database object directly.
@@ -280,7 +282,7 @@ And then, in each *path operation function* that needs to access the database we
But we are not using the value given by this dependency (it actually doesn't give any value, as it has an empty `yield`). So, we don't add it to the *path operation function* but to the *path operation decorator* in the `dependencies` parameter:
```Python hl_lines="32 40 47 59 65 72"
{!./src/sql_databases_peewee/sql_app/main.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
```
### Context variable sub-dependency
@@ -289,8 +291,8 @@ 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"
{!./src/sql_databases_peewee/sql_app/main.py!}
```Python hl_lines="18-20"
{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
```
For the **next request**, as we will reset that context variable again in the `async` dependency `reset_db_state()` and then create a new connection in the `get_db()` dependency, that new request will have its own database state (connection, transactions, etc).
@@ -304,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()
@@ -318,8 +320,8 @@ 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"
{!./src/sql_databases_peewee/sql_app/main.py!}
```Python hl_lines="32-37 40-43 46-53 56-62 65-68 71-79"
{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
```
### About `def` vs `async def`
@@ -369,10 +371,16 @@ async def reset_db_state():
Then run your app with Uvicorn:
```bash
uvicorn sql_app.main:app --reload
<div class="termy">
```console
$ uvicorn sql_app.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/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> and create a couple of users.
Then open 10 tabs at <a href="http://127.0.0.1:8000/docs#/default/read_slow_users_slowusers__get" class="external-link" target="_blank">http://127.0.0.1:8000/docs#/default/read_slow_users_slowusers__get</a> at the same time.
@@ -430,31 +438,31 @@ Repeat the same process with the 10 tabs. This time all of them will wait and yo
* `sql_app/database.py`:
```Python
{!./src/sql_databases_peewee/sql_app/database.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/database.py!}
```
* `sql_app/models.py`:
```Python
{!./src/sql_databases_peewee/sql_app/models.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/models.py!}
```
* `sql_app/schemas.py`:
```Python
{!./src/sql_databases_peewee/sql_app/schemas.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/schemas.py!}
```
* `sql_app/crud.py`:
```Python
{!./src/sql_databases_peewee/sql_app/crud.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/crud.py!}
```
* `sql_app/main.py`:
```Python
{!./src/sql_databases_peewee/sql_app/main.py!}
{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
```
## Technical Details

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

@@ -1,43 +1,53 @@
# Templates
You can use any template engine you want with **FastAPI**.
A common election is Jinja2, the same one used by Flask and other tools.
A common choice is Jinja2, the same one used by Flask and other tools.
Starlette has utilities to configure it easily that you can use directly in your **FastAPI** application.
There are utilities to configure it easily that you can use directly in your **FastAPI** application (provided by Starlette).
## Install dependencies
Install `jinja2`:
```bash
pip install jinja2
<div class="termy">
```console
$ pip install jinja2
---> 100%
```
If you need to also serve static files (as in this example), install `aiofiles`:
```bash
pip install aiofiles
```
</div>
## Using `Jinja2Templates`
* Import `Jinja2Templates` form Starlette.
* Import `Jinja2Templates`.
* Create a `templates` object that you can re-use later.
* Declare a `Request` parameter in the *path operation* that will return a template.
* Use the `templates` you created to render and return a `TemplateResponse`, passing the `request` as one of the key-value pairs in the Jinja2 "context".
```Python hl_lines="4 11 15 16"
{!./src/templates/tutorial001.py!}
```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`.
**FastAPI** provides the same `starlette.templating` as `fastapi.templating` just as a convenience for you, the developer. But most of the available responses come directly from Starlette. The same with `Request` and `StaticFiles`.
## Writing templates
Then you can write a template at `templates/item.html` with:
```jinja hl_lines="7"
{!./src/templates/templates/item.html!}
{!../../../docs_src/templates/templates/item.html!}
```
It will show the `id` taken from the "context" `dict` you passed:
@@ -51,13 +61,13 @@ It will show the `id` taken from the "context" `dict` you passed:
And you can also use `url_for()` inside of the template, and use it, for example, with the `StaticFiles` you mounted.
```jinja hl_lines="4"
{!./src/templates/templates/item.html!}
{!../../../docs_src/templates/templates/item.html!}
```
In this example, it would link to a CSS file at `static/styles.css` with:
```CSS hl_lines="4"
{!./src/templates/static/styles.css!}
{!../../../docs_src/templates/static/styles.css!}
```
And because you are using `StaticFiles`, that CSS file would be served automatically by your **FastAPI** application at the URL `/static/styles.css`.

View File

@@ -0,0 +1,95 @@
# Testing a Database
You can use the same dependency overrides from [Testing Dependencies with Overrides](testing-dependencies.md){.internal-link target=_blank} to alter a database for testing.
You could want to set up a different database for testing, rollback the data after the tests, pre-fill it with some testing data, etc.
The main idea is exactly the same you saw in that previous chapter.
## Add tests for the SQL app
Let's update the example from [SQL (Relational) Databases](../tutorial/sql-databases.md){.internal-link target=_blank} to use a testing database.
All the app code is the same, you can go back to that chapter check how it was.
The only changes here are in the new testing file.
Your normal dependency `get_db()` would return a database session.
In the test, you could use a dependency override to return your *custom* database session instead of the one that would be used normally.
In this example we'll create a temporary database only for the tests.
## File structure
We create a new file at `sql_app/tests/test_sql_app.py`.
So the new file structure looks like:
``` hl_lines="9-11"
.
└── sql_app
├── __init__.py
├── crud.py
├── database.py
├── main.py
├── models.py
├── schemas.py
└── tests
├── __init__.py
└── test_sql_app.py
```
## Create the new database session
First, we create a new database session with the new database.
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-13"
{!../../../docs_src/sql_databases/sql_app/tests/test_sql_app.py!}
```
!!! tip
You could reduce duplication in that code by putting it in a function and using it from both `database.py` and `tests/test_sql_app.py`.
For simplicity and to focus on the specific testing code, we are just copying it.
## Create the database
Because now we are going to use a new database in a new file, we need to make sure we create the database with:
```Python
Base.metadata.create_all(bind=engine)
```
That is normally called in `main.py`, but the line in `main.py` uses the database file `sql_app.db`, and we need to make sure we create `test.db` for the tests.
So we add that line here, with the new file.
```Python hl_lines="16"
{!../../../docs_src/sql_databases/sql_app/tests/test_sql_app.py!}
```
## Dependency override
Now we create the dependency override and add it to the overrides for our app.
```Python hl_lines="19-24 27"
{!../../../docs_src/sql_databases/sql_app/tests/test_sql_app.py!}
```
!!! tip
The code for `override_get_db()` is almost exactly the same as for `get_db()`, but in `override_get_db()` we use the `TestingSessionLocal` for the testing database instead.
## Test the app
Then we can just test the app as normally.
```Python hl_lines="32-47"
{!../../../docs_src/sql_databases/sql_app/tests/test_sql_app.py!}
```
And all the modifications we made in the database during the tests will be in the `test.db` database instead of the main `sql_app.db`.

View File

@@ -1,3 +1,5 @@
# Testing Dependencies with Overrides
## Overriding dependencies during testing
There are some scenarios where you might want to override a dependency during testing.
@@ -18,18 +20,6 @@ You probably want to test the external provider once, but not necessarily call i
In this case, you can override the dependency that calls that provider, and use a custom dependency that returns a mock user, only for your tests.
### Use case: testing database
Other example could be that you are using a specific database only for testing.
Your normal dependency would return a database session.
But then, after each test, you could want to rollback all the operations or remove data.
Or you could want to alter the data before the tests run, etc.
In this case, you could use a dependency override to return your *custom* database session instead of the one that would be used normally.
### Use the `app.dependency_overrides` attribute
For these cases, your **FastAPI** application has an attribute `app.dependency_overrides`, it is a simple `dict`.
@@ -38,8 +28,8 @@ 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"
{!./src/dependency_testing/tutorial001.py!}
```Python hl_lines="26-27 30"
{!../../../docs_src/dependency_testing/tutorial001.py!}
```
!!! tip

View File

@@ -1,7 +1,7 @@
## Testing Events, `startup` and `shutdown`
# Testing Events: startup - shutdown
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"
{!./src/app_testing/tutorial003.py!}
```
```Python hl_lines="9-12 20-24"
{!../../../docs_src/app_testing/tutorial003.py!}
```

View File

@@ -0,0 +1,12 @@
# Testing WebSockets
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-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

@@ -1,3 +1,5 @@
# Using the Request Directly
Up to now, you have been declaring the parts of the request that you need with their types.
Taking data from:
@@ -15,7 +17,7 @@ But there are situations where you might need to access the `Request` object dir
As **FastAPI** is actually **Starlette** underneath, with a layer of several tools on top, you can use Starlette's <a href="https://www.starlette.io/requests/" class="external-link" target="_blank">`Request`</a> object directly when you need to.
It would also mean that if you get data from the `Request` object directly (for example, read the body) it won't be validated, converted or annotated (with OpenAPI, for the automatic documentation) by FastAPI.
It would also mean that if you get data from the `Request` object directly (for example, read the body) it won't be validated, converted or documented (with OpenAPI, for the automatic API user interface) by FastAPI.
Although any other parameter declared normally (for example, the body with a Pydantic model) would still be validated, converted, annotated, etc.
@@ -27,24 +29,14 @@ 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.
### Import the `Request`
First, import the `Request` class from Starlette:
```Python hl_lines="2"
{!./src/using_request_directly/tutorial001.py!}
```Python hl_lines="1 7-8"
{!../../../docs_src/using_request_directly/tutorial001.py!}
```
### Declare the `Request` parameter
Then declare a *path operation function* parameter with the type being the `Request` class:
```Python hl_lines="8"
{!./src/using_request_directly/tutorial001.py!}
```
By declaring a *path operation function* parameter with the type being the `Request` **FastAPI** will know to pass the `Request` in that parameter.
!!! tip
Note that in this case, we are declaring a path parameter besides the request parameter.
Note that in this case, we are declaring a path parameter beside the request parameter.
So, the path parameter will be extracted, validated, converted to the specified type and annotated with OpenAPI.
@@ -53,3 +45,8 @@ Then declare a *path operation function* parameter with the type being the `Requ
## `Request` documentation
You can read more details about the <a href="https://www.starlette.io/requests/" class="external-link" target="_blank">`Request` object in the official Starlette documentation site</a>.
!!! note "Technical Details"
You could also use `from starlette.requests import Request`.
**FastAPI** provides it directly just as a convenience for you, the developer. But it comes directly from Starlette.

View File

@@ -1,3 +1,4 @@
# WebSockets
You can use <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API" class="external-link" target="_blank">WebSockets</a> with **FastAPI**.
@@ -23,71 +24,47 @@ 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 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 39 42 43 44"
{!./src/websockets/tutorial001.py!}
```Python hl_lines="2 6-38 41-43"
{!../../../docs_src/websockets/tutorial001.py!}
```
## Create a `websocket`
In your **FastAPI** application, create a `websocket`:
```Python hl_lines="3 47 48"
{!./src/websockets/tutorial001.py!}
```Python hl_lines="1 46-47"
{!../../../docs_src/websockets/tutorial001.py!}
```
!!! tip
In this example we are importing `WebSocket` from `starlette.websockets` to use it in the type declaration in the WebSocket route function.
!!! note "Technical Details"
You could also use `from starlette.websockets import WebSocket`.
**FastAPI** provides the same `WebSocket` directly just as a convenience for you, the developer. But it comes directly from Starlette.
## Await for messages and send messages
In your WebSocket route you can `await` for messages and send messages.
```Python hl_lines="49 50 51 52 53"
{!./src/websockets/tutorial001.py!}
```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="55 56 57 58 59 60 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78"
{!./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/applications/" class="external-link" target="_blank">Applications (`websocket_route`)</a>.
* <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:
```bash
uvicorn main:app --reload
<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>.
You will see a simple page like:
@@ -107,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

@@ -0,0 +1,37 @@
# Including WSGI - Flask, Django, others
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.
## Using `WSGIMiddleware`
You need to import `WSGIMiddleware`.
Then wrap the WSGI (e.g. Flask) app with the middleware.
And then mount that under a path.
```Python hl_lines="2-3 22"
{!../../../docs_src/wsgi/tutorial001.py!}
```
## Check it
Now, every request under the path `/v1/` will be handled by the Flask application.
And the rest will be handled by **FastAPI**.
If you run it with Uvicorn and go to <a href="http://localhost:8000/v1/" class="external-link" target="_blank">http://localhost:8000/v1/</a> you will see the response from Flask:
```txt
Hello, World from Flask!
```
And if you go to <a href="http://localhost:8000/v2" class="external-link" target="_blank">http://localhost:8000/v2</a> you will see the response from FastAPI:
```JSON
{
"message": "Hello World"
}
```

View File

@@ -1,3 +1,5 @@
# Alternatives, Inspiration and Comparisons
What inspired **FastAPI**, how it compares to other alternatives and what it learned from them.
## Intro
@@ -35,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.
@@ -55,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.
@@ -240,8 +242,6 @@ It was one of the first extremely fast Python frameworks based on `asyncio`. It
Falcon is another high performance Python framework, it is designed to be minimal, and work as the foundation of other frameworks like Hug.
It uses the previous standard for Python web frameworks (WSGI) which is synchronous, so it can't handle WebSockets and other use cases. Nevertheless, it also has a very good performance.
It is designed to have functions that receive two parameters, one "request" and one "response". Then you "read" parts from the request, and "write" parts to the response. Because of this design, it is not possible to declare request parameters and bodies with standard Python type hints as function parameters.
So, data validation, serialization, and documentation, have to be done in code, not automatically. Or they have to be implemented as a framework on top of Falcon, like Hug. This same distinction happens in other frameworks that are inspired by Falcon's design, of having one request object and one response object as parameters.
@@ -274,7 +274,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.
@@ -365,7 +365,6 @@ It has:
* Seriously impressive performance.
* WebSocket support.
* GraphQL support.
* In-process background tasks.
* Startup and shutdown events.
* Test client built on requests.
@@ -373,7 +372,7 @@ It has:
* Session and Cookie support.
* 100% test coverage.
* 100% type annotated codebase.
* Zero hard dependencies.
* Few hard dependencies.
Starlette is currently the fastest Python framework tested. Only surpassed by Uvicorn, which is not a framework, but a server.
@@ -408,7 +407,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

@@ -1,3 +1,5 @@
# Concurrency and async / await
Details about the `async def` syntax for *path operation functions* and some background about asynchronous code, concurrency, and parallelism.
## In a hurry?
@@ -53,7 +55,7 @@ But by following the steps above, it will be able to do some performance optimiz
Modern versions of Python have support for **"asynchronous code"** using something called **"coroutines"**, with **`async` and `await`** syntax.
Let's see that phrase by parts in the sections below, below:
Let's see that phrase by parts in the sections below:
* **Asynchronous Code**
* **`async` and `await`**
@@ -61,13 +63,13 @@ Let's see that phrase by parts in the sections below, below:
## Asynchronous Code
Asynchronous code just means that the language has a way to tell the computer / program that at some point in the code, he will have to wait for *something else* to finish somewhere else. Let's say that *something else* is called "slow-file".
Asynchronous code just means that the language 💬 has a way to tell the computer / program 🤖 that at some point in the code, it 🤖 will have to wait for *something else* to finish somewhere else. Let's say that *something else* is called "slow-file" 📝.
So, during that time, the computer can go and do some other work, while "slow-file" finishes.
So, during that time, the computer can go and do some other work, while "slow-file" 📝 finishes.
Then the computer / program will come back every time it has a chance because it's waiting again, or whenever he finished all the work he had at that point. And it will see if any of the tasks he was waiting for has already finished doing whatever it had to do.
Then the computer / program 🤖 will come back every time it has a chance because it's waiting again, or whenever it 🤖 finished all the work it had at that point. And it 🤖 will see if any of the tasks it was waiting for have already finished, doing whatever it had to do.
And then it takes the first task to finish (let's say, our "slow-file") and continues whatever it had to do with it.
Next, it 🤖 takes the first task to finish (let's say, our "slow-file" 📝) and continues whatever it had to do with it.
That "wait for something else" normally refers to <abbr title="Input and Output">I/O</abbr> operations that are relatively "slow" (compared to the speed of the processor and the RAM memory), like waiting for:
@@ -80,7 +82,7 @@ That "wait for something else" normally refers to <abbr title="Input and Output"
* a database query to return the results
* etc.
As the execution time is consumed mostly by waiting for <abbr title="Input and Output">I/O</abbr> operations, so they call them "I/O bound".
As the execution time is consumed mostly by waiting for <abbr title="Input and Output">I/O</abbr> operations, they call them "I/O bound" operations.
It's called "asynchronous" because the computer / program doesn't have to be "synchronized" with the slow task, waiting for the exact moment that the task finishes, while doing nothing, to be able to take the task result and continue the work.
@@ -92,7 +94,7 @@ For "synchronous" (contrary to "asynchronous") they commonly also use the term "
This idea of **asynchronous** code described above is also sometimes called **"concurrency"**. It is different from **"parallelism"**.
**Concurrency** and **parallelism** both relate to "different things happening more or less at the same time".
**Concurrency** and **parallelism** both relate to "different things happening more or less at the same time".
But the details between *concurrency* and *parallelism* are quite different.
@@ -100,115 +102,119 @@ To see the difference, imagine the following story about burgers:
### Concurrent Burgers
You go with your crush to get fast food, you stand in line while the cashier takes the orders from the people in front of you.
<!-- The gender neutral cook emoji "🧑‍🍳" does not render well in browsers. In the meantime, I'm using a mix of male "👨‍🍳" and female "👩‍🍳" cooks. -->
Then it's your turn, you place your order of 2 very fancy burgers for your crush and you.
You go with your crush 😍 to get fast food 🍔, you stand in line while the cashier 💁 takes the orders from the people in front of you.
You pay.
Then it's your turn, you place your order of 2 very fancy burgers 🍔 for your crush 😍 and you.
The cashier says something to the guy in the kitchen so he knows he has to prepare your burgers (even though he is currently preparing the ones for the previous clients).
You pay 💸.
The cashier gives you the number of your turn.
The cashier 💁 says something to the cook in the kitchen 👨‍🍳 so they know they have to prepare your burgers 🍔 (even though they are currently preparing the ones for the previous clients).
While you are waiting, you go with your crush and pick a table, you sit and talk with your crush for a long time (as your burgers are very fancy and take some time to prepare).
The cashier 💁 gives you the number of your turn.
As you are seating on the table with your crush, while you wait for the burgers, you can spend that time admiring how awesome, cute and smart your crush is.
While you are waiting, you go with your crush 😍 and pick a table, you sit and talk with your crush 😍 for a long time (as your burgers are very fancy and take some time to prepare ✨🍔✨).
While waiting and talking to your crush, from time to time, you check the number displayed on the counter to see if it's your turn already.
As you are sitting on the table with your crush 😍, while you wait for the burgers 🍔, you can spend that time admiring how awesome, cute and smart your crush is ✨😍✨.
Then at some point, it finally is your turn. You go to the counter, get your burgers and come back to the table.
While waiting and talking to your crush 😍, from time to time, you check the number displayed on the counter to see if it's your turn already.
You and your crush eat the burgers and have a nice time.
Then at some point, it finally is your turn. You go to the counter, get your burgers 🍔 and come back to the table.
You and your crush 😍 eat the burgers 🍔 and have a nice time ✨.
---
Imagine you are the computer / program in that story.
Imagine you are the computer / program 🤖 in that story.
While you are at the line, you are just idle, waiting for your turn, not doing anything very "productive". But the line is fast because the cashier is only taking the orders, so that's fine.
While you are at the line, you are just idle 😴, waiting for your turn, not doing anything very "productive". But the line is fast because the cashier 💁 is only taking the orders (not preparing them), so that's fine.
Then, when it's your turn, you do actual "productive" work, you process the menu, decide what you want, get your crush's choice, pay, check that you give the correct bill or card, check that you are charged correctly, check that the order has the correct items, etc.
Then, when it's your turn, you do actual "productive" work 🤓, you process the menu, decide what you want, get your crush's 😍 choice, pay 💸, check that you give the correct bill or card, check that you are charged correctly, check that the order has the correct items, etc.
But then, even though you still don't have your burgers, your work with the cashier is "on pause", because you have to wait for your burgers to be ready.
But then, even though you still don't have your burgers 🍔, your work with the cashier 💁 is "on pause", because you have to wait 🕙 for your burgers to be ready.
But as you go away from the counter and seat on the table with a number for your turn, you can switch your attention to your crush, and "work" on that. Then you are again doing something very "productive", as is flirting with your crush.
But as you go away from the counter and sit on the table with a number for your turn, you can switch 🔀 your attention to your crush 😍, and "work" ⏯ 🤓 on that. Then you are again doing something very "productive" 🤓, as is flirting with your crush 😍.
Then the cashier says "I'm finished with doing the burgers" by putting your number on the counter display, but you don't jump like crazy immediately when the displayed number changes to your turn number. You know no one will steal your burgers because you have the number of your turn, and they have theirs.
Then the cashier 💁 says "I'm finished with doing the burgers" 🍔 by putting your number on the counter's display, but you don't jump like crazy immediately when the displayed number changes to your turn number. You know no one will steal your burgers 🍔 because you have the number of your turn, and they have theirs.
So you wait for your crush to finish the story (finish the current work / task being processed), smile gently and say that you are going for the burgers.
So you wait for your crush 😍 to finish the story (finish the current work / task being processed 🤓), smile gently and say that you are going for the burgers.
Then you go to the counter, to the initial task that is now finished, pick the burgers, say thanks and take them to the table. That finishes that step / task of interaction with the counter. That in turn, creates a new task, of "eating burgers", but the previous one of "getting burgers" is finished.
Then you go to the counter 🔀, to the initial task that is now finished, pick the burgers 🍔, say thanks and take them to the table. That finishes that step / task of interaction with the counter. That in turn, creates a new task, of "eating burgers" 🔀 ⏯, but the previous one of "getting burgers" is finished.
### Parallel Burgers
You go with your crush to get parallel fast food.
Now let's imagine these aren't "Concurrent Burgers", but "Parallel Burgers".
You stand in line while several (let's say 8) cashiers take the orders from the people in front of you.
You go with your crush 😍 to get parallel fast food 🍔.
Everyone before you is waiting for their burgers to be ready before leaving the counter because each of the 8 cashiers goes himself and prepares the burger right away before getting the next order.
You stand in line while several (let's say 8) cashiers that at the same time are cooks 👩‍🍳👨‍🍳👩‍🍳👨‍🍳👩‍🍳👨‍🍳👩‍🍳👨‍🍳 take the orders from the people in front of you.
Then it's finally your turn, you place your order of 2 very fancy burgers for your crush and you.
Everyone before you is waiting 🕙 for their burgers 🍔 to be ready before leaving the counter because each of the 8 cashiers goes and prepares the burger right away before getting the next order.
You pay.
Then it's finally your turn, you place your order of 2 very fancy burgers 🍔 for your crush 😍 and you.
The cashier goes to the kitchen.
You pay 💸.
You wait, standing in front of the counter, so that no one else takes your burgers before you, as there are no numbers for turns.
The cashier goes to the kitchen 👨‍🍳.
As you and your crush are busy not letting anyone get in front of you and take your burgers whenever they arrive, you cannot pay attention to your crush.
You wait, standing in front of the counter 🕙, so that no one else takes your burgers 🍔 before you do, as there are no numbers for turns.
This is "synchronous" work, you are "synchronized" with the cashier/cook. You have to wait and be there at the exact moment that the cashier/cook finishes the burgers and gives them to you, or otherwise, someone else might take them.
As you and your crush 😍 are busy not letting anyone get in front of you and take your burgers whenever they arrive 🕙, you cannot pay attention to your crush 😞.
Then your cashier/cook finally comes back with your burgers, after a long time waiting there in front of the counter.
This is "synchronous" work, you are "synchronized" with the cashier/cook 👨‍🍳. You have to wait 🕙 and be there at the exact moment that the cashier/cook 👨‍🍳 finishes the burgers 🍔 and gives them to you, or otherwise, someone else might take them.
You take your burgers and go to the table with your crush.
Then your cashier/cook 👨‍🍳 finally comes back with your burgers 🍔, after a long time waiting 🕙 there in front of the counter.
You just eat them, and you are done.
You take your burgers 🍔 and go to the table with your crush 😍.
There was not much talk or flirting as most of the time was spent waiting in front of the counter.
You just eat them, and you are done 🍔 ⏹.
There was not much talk or flirting as most of the time was spent waiting 🕙 in front of the counter 😞.
---
In this scenario of the parallel burgers, you are a computer / program with two processors (you and your crush), both waiting and dedicating their attention to be "waiting on the counter" for a long time.
In this scenario of the parallel burgers, you are a computer / program 🤖 with two processors (you and your crush 😍), both waiting 🕙 and dedicating their attention to be "waiting on the counter" 🕙 for a long time.
The fast food store has 8 processors (cashiers/cooks). While the concurrent burgers store might have had only 2 (one cashier and one cook).
The fast food store has 8 processors (cashiers/cooks) 👩‍🍳👨‍🍳👩‍🍳👨‍🍳👩‍🍳👨‍🍳👩‍🍳👨‍🍳. While the concurrent burgers store might have had only 2 (one cashier and one cook) 💁 👨‍🍳.
But still, the final experience is not the best.
But still, the final experience is not the best 😞.
---
This would be the parallel equivalent story for burgers.
This would be the parallel equivalent story for burgers 🍔.
For a more "real life" example of this, imagine a bank.
Up to recently, most of the banks had multiple cashiers and a big line.
Up to recently, most of the banks had multiple cashiers 👨‍💼👨‍💼👨‍💼👨‍💼 and a big line 🕙🕙🕙🕙🕙🕙🕙🕙.
All of the cashiers doing all the work with one client after the other.
All of the cashiers doing all the work with one client after the other 👨‍💼⏯.
And you have to wait in the line for a long time or you lose your turn.
And you have to wait 🕙 in the line for a long time or you lose your turn.
You probably wouldn't want to take your crush with you to do errands at the bank.
You probably wouldn't want to take your crush 😍 with you to do errands at the bank 🏦.
### Burger Conclusion
In this scenario of "fast food burgers with your crush", as there is a lot of waiting, it makes a lot more sense to have a concurrent system.
In this scenario of "fast food burgers with your crush", as there is a lot of waiting 🕙, it makes a lot more sense to have a concurrent system ⏸🔀⏯.
This is the case for most of the web applications.
Many, many users, but your server is waiting for their not-so-good connection to send their requests.
Many, many users, but your server is waiting 🕙 for their not-so-good connection to send their requests.
And then waiting again for the responses to come back.
And then waiting 🕙 again for the responses to come back.
This "waiting" is measured in microseconds, but still, summing it all, it's a lot of waiting in the end.
This "waiting" 🕙 is measured in microseconds, but still, summing it all, it's a lot of waiting in the end.
That's why it makes a lot of sense to use asynchronous code for web APIs.
That's why it makes a lot of sense to use asynchronous ⏸🔀⏯ code for web APIs.
Most of the existing popular Python frameworks (including Flask and Django) were created before the new asynchronous features in Python existed. So, the ways they can be deployed support parallel execution and an older form of asynchronous execution that is not as powerful as the new capabilities.
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</a> you get with **FastAPI**.
And that's the same level of performance you get with **FastAPI**.
And as you can have parallelism and asynchronicity at the same time, you get higher performance than most of the tested NodeJS frameworks and on par with Go, which is a compiled language closer to C <a href="https://www.techempower.com/benchmarks/#section=data-r17&hw=ph&test=query&l=zijmkf-1" class="external-link" target="_blank">(all thanks to Starlette)</a>.
@@ -226,15 +232,15 @@ So, to balance that out, imagine the following short story:
---
There's no waiting anywhere, just a lot of work to be done, on multiple places of the house.
There's no waiting 🕙 anywhere, just a lot of work to be done, on multiple places of the house.
You could have turns as in the burgers example, first the living room, then the kitchen, but as you are not waiting for anything, just cleaning and cleaning, the turns wouldn't affect anything.
You could have turns as in the burgers example, first the living room, then the kitchen, but as you are not waiting 🕙 for anything, just cleaning and cleaning, the turns wouldn't affect anything.
It would take the same amount of time to finish with or without turns (concurrency) and you would have done the same amount of work.
But in this case, if you could bring the 8 ex-cashier/cooks/now-cleaners, and each one of them (plus you) could take a zone of the house to clean it, you could do all the work in **parallel**, with the extra help, and finish much sooner.
But in this case, if you could bring the 8 ex-cashier/cooks/now-cleaners 👩‍🍳👨‍🍳👩‍🍳👨‍🍳👩‍🍳👨‍🍳👩‍🍳👨‍🍳, and each one of them (plus you) could take a zone of the house to clean it, you could do all the work in **parallel**, with the extra help, and finish much sooner.
In this scenario, each one of the cleaners (including you) would be a processor, doing their part of the job.
In this scenario, each one of the cleaners (including you) would be a processor, doing their part of the job.
And as most of the execution time is taken by actual work (instead of waiting), and the work in a computer is done by a <abbr title="Central Processing Unit">CPU</abbr>, they call these problems "CPU bound".
@@ -244,8 +250,8 @@ Common examples of CPU bound operations are things that require complex math pro
For example:
* **Audio** or **image processing**
* **Computer vision**: an image is composed of millions of pixels, each pixel has 3 values / colors, processing that normally requires computing something on those pixels, all at the same time)
* **Audio** or **image processing**.
* **Computer vision**: an image is composed of millions of pixels, each pixel has 3 values / colors, processing that normally requires computing something on those pixels, all at the same time.
* **Machine Learning**: it normally requires lots of "matrix" and "vector" multiplications. Think of a huge spreadsheet with numbers and multiplying all of them together at the same time.
* **Deep Learning**: this is a sub-field of Machine Learning, so, the same applies. It's just that there is not a single spreadsheet of numbers to multiply, but a huge set of them, and in many cases, you use a special processor to build and / or use those models.
@@ -257,11 +263,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:
@@ -269,7 +275,7 @@ When there is an operation that will require waiting before giving the results a
burgers = await get_burgers(2)
```
The key here is the `await`. It tells Python that it has to wait for `get_burgers(2)` to finish doing its thing before storing the results in `burgers`. With that, Python will know that it can go and do something else in the meanwhile (like receiving another request).
The key here is the `await`. It tells Python that it has to wait for `get_burgers(2)` to finish doing its thing 🕙 before storing the results in `burgers`. With that, Python will know that it can go and do something else 🔀 ⏯ in the meanwhile (like receiving another request).
For `await` to work, it has to be inside a function that supports this asynchronicity. To do that, you just declare it with `async def`:
@@ -288,7 +294,7 @@ def get_sequential_burgers(number: int):
return burgers
```
With `async def`, Python knows that, inside that function, it has to be aware of `await` expressions, and that it can "pause" the execution of that function and go do something else before coming back.
With `async def`, Python knows that, inside that function, it has to be aware of `await` expressions, and that it can "pause" the execution of that function and go do something else 🔀 before coming back.
When you want to call an `async def` function, you have to "await" it. So, this won't work:
@@ -301,7 +307,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)
@@ -318,7 +324,15 @@ So, about the egg and the chicken, how do you call the first `async` function?
If you are working with **FastAPI** you don't have to worry about that, because that "first" function will be your *path operation function*, and FastAPI will know how to do the right thing.
But if you want to use `async` / `await` without FastAPI, <a href="https://docs.python.org/3/library/asyncio-task.html#coroutine" class="external-link" target="_blank">check the official Python docs</a>.
But if you want to use `async` / `await` without FastAPI, you can do it as well.
### Write your own async code
Starlette (and **FastAPI**) are based on <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a>, which makes it compatible with both Python's standard library <a href="https://docs.python.org/3/library/asyncio-task.html" class="external-link" target="_blank">asyncio</a> and <a href="https://trio.readthedocs.io/en/stable/" class="external-link" target="_blank">Trio</a>.
In particular, you can directly use <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a> for your advanced concurrency use cases that require more advanced patterns in your own code.
And even if you were not using FastAPI, you could also write your own async applications with <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a> to be highly compatible and get its benefits (e.g. *structured concurrency*).
### Other forms of asynchronous code
@@ -330,13 +344,13 @@ 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
**Coroutine** is just the very fancy term for the thing returned by an `async def` function. Python knows that it is something like a function that it can start and that it will end at some point, but that it might be paused internally too, whenever there is an `await` inside of it.
**Coroutine** is just the very fancy term for the thing returned by an `async def` function. Python knows that it is something like a function that it can start and that it will end at some point, but that it might be paused internally too, whenever there is an `await` inside of it.
But all this functionality of using asynchronous code with `async` and `await` is many times summarized as using "coroutines". It is comparable to the main key feature of Go, the "Goroutines".
@@ -346,7 +360,7 @@ Let's see the same phrase from above:
> Modern versions of Python have support for **"asynchronous code"** using something called **"coroutines"**, with **`async` and `await`** syntax.
That should make more sense now.
That should make more sense now.
All that is what powers FastAPI (through Starlette) and what makes it have such an impressive performance.
@@ -354,16 +368,16 @@ All that is what powers FastAPI (through Starlette) and what makes it have such
!!! warning
You can probably skip this.
These are very technical details of how **FastAPI** works underneath.
If you have quite some technical knowledge (co-routines, threads, blocking, etc) and are curious about how FastAPI handles `async def` vs normal `def`, go ahead.
### Path operation functions
When you declare a *path operation function* with normal `def` instead of `async def`, it is run in an external threadpool that is then awaited, instead of being called directly (as it would block the server).
If you are coming from another async framework that does not work in the way described above and you are used to define trivial compute-only *path operation functions* with plain `def` for a tiny performance gain (about 100 nanoseconds), please note that in **FastAPI** the effect would be quite opposite. In these cases, it's better to use `async def` unless your *path operation functions* use code that performs blocking <abbr title="Input/Output: disk reading or writing, network communications.">IO</abbr>.
If you are coming from another async framework that does not work in the way described above and you are used to define trivial compute-only *path operation functions* with plain `def` for a tiny performance gain (about 100 nanoseconds), please note that in **FastAPI** the effect would be quite opposite. In these cases, it's better to use `async def` unless your *path operation functions* use code that performs blocking <abbr title="Input/Output: disk reading or writing, network communications.">I/O</abbr>.
Still, in both situations, chances are that **FastAPI** will [still be faster](/#performance){.internal-link target=_blank} than (or at least comparable to) your previous framework.
@@ -373,7 +387,7 @@ The same applies for dependencies. If a dependency is a standard `def` function
### Sub-dependencies
You can have multiple dependencies and sub-dependencies requiring each other (as parameters of the function definitions), some of them might be created with `async def` and some with normal `def`. It would still work, and the ones created with normal `def` would be called on an external thread instead of being "awaited".
You can have multiple dependencies and sub-dependencies requiring each other (as parameters of the function definitions), some of them might be created with `async def` and some with normal `def`. It would still work, and the ones created with normal `def` would be called on an external thread (from the threadpool) instead of being "awaited".
### Other utility functions
@@ -381,7 +395,7 @@ Any other utility function that you call directly can be created with normal `de
This is in contrast to the functions that FastAPI calls for you: *path operation functions* and dependencies.
If your utility function is a normal function with `def`, it will be called directly (as you write it in your code), not in a threadpool, if the function is created with `async def` then you should await for that function when you call it in your code.
If your utility function is a normal function with `def`, it will be called directly (as you write it in your code), not in a threadpool, if the function is created with `async def` then you should `await` for that function when you call it in your code.
---

View File

@@ -1,3 +1,5 @@
# Benchmarks
Independent TechEmpower benchmarks show **FastAPI** applications running under Uvicorn as <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">one of the fastest Python frameworks available</a>, only below Starlette and Uvicorn themselves (used internally by FastAPI). (*)
But when checking benchmarks and comparisons you should have the following in mind.
@@ -8,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

@@ -0,0 +1,487 @@
# Development - Contributing
First, you might want to see the basic ways to [help FastAPI and get help](help-fastapi.md){.internal-link target=_blank}.
## Developing
If you already cloned the repository and you know that you need to deep dive in the code, here are some guidelines to set up your environment.
### Virtual environment with `venv`
You can create a virtual environment in a directory using Python's `venv` module:
<div class="termy">
```console
$ python -m venv env
```
</div>
That will create a directory `./env/` with the Python binaries and then you will be able to install packages for that isolated environment.
### Activate the environment
Activate the new environment with:
=== "Linux, macOS"
<div class="termy">
```console
$ source ./env/bin/activate
```
</div>
=== "Windows PowerShell"
<div class="termy">
```console
$ .\env\Scripts\Activate.ps1
```
</div>
=== "Windows Bash"
Or if you use Bash for Windows (e.g. <a href="https://gitforwindows.org/" class="external-link" target="_blank">Git Bash</a>):
<div class="termy">
```console
$ source ./env/Scripts/activate
```
</div>
To check it worked, use:
=== "Linux, macOS, Windows Bash"
<div class="termy">
```console
$ which pip
some/directory/fastapi/env/bin/pip
```
</div>
=== "Windows PowerShell"
<div class="termy">
```console
$ Get-Command pip
some/directory/fastapi/env/bin/pip
```
</div>
If it shows the `pip` binary at `env/bin/pip` then it worked. 🎉
!!! tip
Every time you install a new package with `pip` under that environment, activate the environment again.
This makes sure that if you use a terminal program installed by that package (like `flit`), you use the one from your local environment and not any other that could be installed globally.
### Flit
**FastAPI** uses <a href="https://flit.readthedocs.io/en/latest/index.html" class="external-link" target="_blank">Flit</a> to build, package and publish the project.
After activating the environment as described above, install `flit`:
<div class="termy">
```console
$ pip install flit
---> 100%
```
</div>
Now re-activate the environment to make sure you are using the `flit` you just installed (and not a global one).
And now use `flit` to install the development dependencies:
=== "Linux, macOS"
<div class="termy">
```console
$ flit install --deps develop --symlink
---> 100%
```
</div>
=== "Windows"
If you are on Windows, use `--pth-file` instead of `--symlink`:
<div class="termy">
```console
$ flit install --deps develop --pth-file
---> 100%
```
</div>
It will install all the dependencies and your local FastAPI in your local environment.
#### Using your local FastAPI
If you create a Python file that imports and uses FastAPI, and run it with the Python from your local environment, it will use your local FastAPI source code.
And if you update that local FastAPI source code, as it is installed with `--symlink` (or `--pth-file` on Windows), when you run that Python file again, it will use the fresh version of FastAPI you just edited.
That way, you don't have to "install" your local version to be able to test every change.
### Format
There is a script that you can run that will format and clean all your code:
<div class="termy">
```console
$ bash scripts/format.sh
```
</div>
It will also auto-sort all your imports.
For it to sort them correctly, you need to have FastAPI installed locally in your environment, with the command in the section above using `--symlink` (or `--pth-file` on Windows).
## Docs
First, make sure you set up your environment as described above, that will install all the requirements.
The documentation uses <a href="https://www.mkdocs.org/" class="external-link" target="_blank">MkDocs</a>.
And there are extra tools/scripts in place to handle translations in `./scripts/docs.py`.
!!! tip
You don't need to see the code in `./scripts/docs.py`, you just use it in the command line.
All the documentation is in Markdown format in the directory `./docs/en/`.
Many of the tutorials have blocks of code.
In most of the cases, these blocks of code are actual complete applications that can be run as is.
In fact, those blocks of code are not written inside the Markdown, they are Python files in the `./docs_src/` directory.
And those Python files are included/injected in the documentation when generating the site.
### Docs for tests
Most of the tests actually run against the example source files in the documentation.
This helps making sure that:
* The documentation is up to date.
* The documentation examples can be run as is.
* Most of the features are covered by the documentation, ensured by test coverage.
During local development, there is a script that builds the site and checks for any changes, live-reloading:
<div class="termy">
```console
$ python ./scripts/docs.py live
<span style="color: green;">[INFO]</span> Serving on http://127.0.0.1:8008
<span style="color: green;">[INFO]</span> Start watching changes
<span style="color: green;">[INFO]</span> Start detecting changes
```
</div>
It will serve the documentation on `http://127.0.0.1:8008`.
That way, you can edit the documentation/source files and see the changes live.
#### Typer CLI (optional)
The instructions here show you how to use the script at `./scripts/docs.py` with the `python` program directly.
But you can also use <a href="https://typer.tiangolo.com/typer-cli/" class="external-link" target="_blank">Typer CLI</a>, and you will get autocompletion in your terminal for the commands after installing completion.
If you install Typer CLI, you can install completion with:
<div class="termy">
```console
$ typer --install-completion
zsh completion installed in /home/user/.bashrc.
Completion will take effect once you restart the terminal.
```
</div>
### Apps and docs at the same time
If you run the examples with, e.g.:
<div class="termy">
```console
$ uvicorn tutorial001:app --reload
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
as Uvicorn by default will use the port `8000`, the documentation on port `8008` won't clash.
### Translations
Help with translations is VERY MUCH appreciated! And it can't be done without the help from the community. 🌎 🚀
Here are the steps to help with translations.
#### Tips and guidelines
* Check the currently <a href="https://github.com/tiangolo/fastapi/pulls" class="external-link" target="_blank">existing pull requests</a> for your language and add reviews requesting changes or approving them.
!!! tip
You can <a href="https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request" class="external-link" target="_blank">add comments with change suggestions</a> to existing pull requests.
Check the docs about <a href="https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-request-reviews" class="external-link" target="_blank">adding a pull request review</a> to approve it or request changes.
* Check in the <a href="https://github.com/tiangolo/fastapi/issues" class="external-link" target="_blank">issues</a> to see if there's one coordinating translations for your language.
* Add a single pull request per page translated. That will make it much easier for others to review it.
For the languages I don't speak, I'll wait for several others to review the translation before merging.
* You can also check if there are translations for your language and add a review to them, that will help me know that the translation is correct and I can merge it.
* Use the same Python examples and only translate the text in the docs. You don't have to change anything for this to work.
* Use the same images, file names, and links. You don't have to change anything for it to work.
* To check the 2-letter code for the language you want to translate you can use the table <a href="https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes" class="external-link" target="_blank">List of ISO 639-1 codes</a>.
#### Existing language
Let's say you want to translate a page for a language that already has translations for some pages, like Spanish.
In the case of Spanish, the 2-letter code is `es`. So, the directory for Spanish translations is located at `docs/es/`.
!!! tip
The main ("official") language is English, located at `docs/en/`.
Now run the live server for the docs in Spanish:
<div class="termy">
```console
// Use the command "live" and pass the language code as a CLI argument
$ python ./scripts/docs.py live es
<span style="color: green;">[INFO]</span> Serving on http://127.0.0.1:8008
<span style="color: green;">[INFO]</span> Start watching changes
<span style="color: green;">[INFO]</span> Start detecting changes
```
</div>
Now you can go to <a href="http://127.0.0.1:8008" class="external-link" target="_blank">http://127.0.0.1:8008</a> and see your changes live.
If you look at the FastAPI docs website, you will see that every language has all the pages. But some pages are not translated and have a notification about the missing translation.
But when you run it locally like this, you will only see the pages that are already translated.
Now let's say that you want to add a translation for the section [Features](features.md){.internal-link target=_blank}.
* Copy the file at:
```
docs/en/docs/features.md
```
* Paste it in exactly the same location but for the language you want to translate, e.g.:
```
docs/es/docs/features.md
```
!!! tip
Notice that the only change in the path and file name is the language code, from `en` to `es`.
* Now open the MkDocs config file for English at:
```
docs/en/mkdocs.yml
```
* Find the place where that `docs/features.md` is located in the config file. Somewhere like:
```YAML hl_lines="8"
site_name: FastAPI
# More stuff
nav:
- FastAPI: index.md
- Languages:
- en: /
- es: /es/
- features.md
```
* Open the MkDocs config file for the language you are editing, e.g.:
```
docs/es/mkdocs.yml
```
* Add it there at the exact same location it was for English, e.g.:
```YAML hl_lines="8"
site_name: FastAPI
# More stuff
nav:
- FastAPI: index.md
- Languages:
- en: /
- es: /es/
- features.md
```
Make sure that if there are other entries, the new entry with your translation is exactly in the same order as in the English version.
If you go to your browser you will see that now the docs show your new section. 🎉
Now you can translate it all and see how it looks as you save the file.
#### New Language
Let's say that you want to add translations for a language that is not yet translated, not even some pages.
Let's say you want to add translations for Creole, and it's not yet there in the docs.
Checking the link from above, the code for "Creole" is `ht`.
The next step is to run the script to generate a new translation directory:
<div class="termy">
```console
// Use the command new-lang, pass the language code as a CLI argument
$ python ./scripts/docs.py new-lang ht
Successfully initialized: docs/ht
Updating ht
Updating en
```
</div>
Now you can check in your code editor the newly created directory `docs/ht/`.
!!! tip
Create a first pull request with just this, to set up the configuration for the new language, before adding translations.
That way others can help with other pages while you work on the first one. 🚀
Start by translating the main page, `docs/ht/index.md`.
Then you can continue with the previous instructions, for an "Existing Language".
##### New Language not supported
If when running the live server script you get an error about the language not being supported, something like:
```
raise TemplateNotFound(template)
jinja2.exceptions.TemplateNotFound: partials/language/xx.html
```
That means that the theme doesn't support that language (in this case, with a fake 2-letter code of `xx`).
But don't worry, you can set the theme language to English and then translate the content of the docs.
If you need to do that, edit the `mkdocs.yml` for your new language, it will have something like:
```YAML hl_lines="5"
site_name: FastAPI
# More stuff
theme:
# More stuff
language: xx
```
Change that language from `xx` (from your language code) to `en`.
Then you can start the live server again.
#### Preview the result
When you use the script at `./scripts/docs.py` with the `live` command it only shows the files and translations available for the current language.
But once you are done, you can test it all as it would look online.
To do that, first build all the docs:
<div class="termy">
```console
// Use the command "build-all", this will take a bit
$ python ./scripts/docs.py build-all
Updating es
Updating en
Building docs for: en
Building docs for: es
Successfully built docs for: es
Copying en index.md to README.md
```
</div>
That generates all the docs at `./docs_build/` for each language. This includes adding any files with missing translations, with a note saying that "this file doesn't have a translation yet". But you don't have to do anything with that directory.
Then it builds all those independent MkDocs sites for each language, combines them, and generates the final output at `./site/`.
Then you can serve that with the command `serve`:
<div class="termy">
```console
// Use the command "serve" after running "build-all"
$ python ./scripts/docs.py serve
Warning: this is a very simple server. For development, use mkdocs serve instead.
This is here only to preview a site with translations already built.
Make sure you run the build-all command first.
Serving at: http://127.0.0.1:8008
```
</div>
## Tests
There is a script that you can run locally to test all the code and generate coverage reports in HTML:
<div class="termy">
```console
$ 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.

120
docs/en/docs/css/custom.css Normal file
View File

@@ -0,0 +1,120 @@
.termynal-comment {
color: #4a968f;
font-style: italic;
display: block;
}
.termy [data-termynal] {
white-space: pre-wrap;
}
a.external-link::after {
/* \00A0 is a non-breaking space
to make the mark be on the same line as the link
*/
content: "\00A0[↪]";
}
a.internal-link::after {
/* \00A0 is a non-breaking space
to make the mark be on the same line as the link
*/
content: "\00A0↪";
}
.shadow {
box-shadow: 5px 5px 10px #999;
}
/* 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;
margin-bottom: 2rem;
}
.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;
}
a.announce-link:link,
a.announce-link:visited {
color: #fff;
}
a.announce-link:hover {
color: var(--md-accent-fg-color);
}
.announce-wrapper {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
align-items: center;
}
.announce-wrapper div.item {
display: none;
}
.announce-wrapper .sponsor-badge {
display: block;
position: absolute;
top: -5px;
right: 0;
font-size: 0.5rem;
color: #999;
background-color: #666;
border-radius: 10px;
padding: 0 10px;
z-index: 10;
}
.announce-wrapper .sponsor-image {
display: block;
border-radius: 20px;
}
.announce-wrapper>div {
min-height: 40px;
display: flex;
align-items: center;
}
.twitter {
color: #00acee;
}

View File

@@ -0,0 +1,109 @@
/**
* termynal.js
*
* @author Ines Montani <ines@ines.io>
* @version 0.0.1
* @license MIT
*/
:root {
--color-bg: #252a33;
--color-text: #eee;
--color-text-subtle: #a2a2a2;
}
[data-termynal] {
width: 750px;
max-width: 100%;
background: var(--color-bg);
color: var(--color-text);
/* font-size: 18px; */
font-size: 15px;
/* font-family: 'Fira Mono', Consolas, Menlo, Monaco, 'Courier New', Courier, monospace; */
font-family: 'Roboto Mono', 'Fira Mono', Consolas, Menlo, Monaco, 'Courier New', Courier, monospace;
border-radius: 4px;
padding: 75px 45px 35px;
position: relative;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
[data-termynal]:before {
content: '';
position: absolute;
top: 15px;
left: 15px;
display: inline-block;
width: 15px;
height: 15px;
border-radius: 50%;
/* A little hack to display the window buttons in one pseudo element. */
background: #d9515d;
-webkit-box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930;
box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930;
}
[data-termynal]:after {
content: 'bash';
position: absolute;
color: var(--color-text-subtle);
top: 5px;
left: 0;
width: 100%;
text-align: center;
}
a[data-terminal-control] {
text-align: right;
display: block;
color: #aebbff;
}
[data-ty] {
display: block;
line-height: 2;
}
[data-ty]:before {
/* Set up defaults and ensure empty lines are displayed. */
content: '';
display: inline-block;
vertical-align: middle;
}
[data-ty="input"]:before,
[data-ty-prompt]:before {
margin-right: 0.75em;
color: var(--color-text-subtle);
}
[data-ty="input"]:before {
content: '$';
}
[data-ty][data-ty-prompt]:before {
content: attr(data-ty-prompt);
}
[data-ty-cursor]:after {
content: attr(data-ty-cursor);
font-family: monospace;
margin-left: 0.5em;
-webkit-animation: blink 1s infinite;
animation: blink 1s infinite;
}
/* Cursor animation */
@-webkit-keyframes blink {
50% {
opacity: 0;
}
}
@keyframes blink {
50% {
opacity: 0;
}
}

View File

@@ -0,0 +1,311 @@
# Deployments Concepts
When deploying a **FastAPI** application, or actually, any type of web API, there are several concepts that you probably care about, and using them you can find the **most appropriate** way to **deploy your application**.
Some of the important concepts are:
* Security - HTTPS
* Running on startup
* Restarts
* Replication (the number of processes running)
* Memory
* Previous steps before starting
We'll see how they would affect **deployments**.
In the end, the ultimate objective is to be able to **serve your API clients** in a way that is **secure**, to **avoid disruptions**, and to use the **compute resources** (for example remote servers/virtual machines) as efficiently as possible. 🚀
I'll tell you a bit more about these **concepts** here, and that would hopefully give you the **intuition** you would need to decide how to deploy your API in very different environments, possibly even in **future** ones that don't exist yet.
By considering these concepts, you will be able to **evaluate and design** the best way to deploy **your own APIs**.
In the next chapters, I'll give you more **concrete recipes** to deploy FastAPI applications.
But for now, let's check these important **conceptual ideas**. These concepts also apply to any other type of web API. 💡
## Security - HTTPS
In the [previous chapter about HTTPS](./https.md){.internal-link target=_blank} we learned about how HTTPS provides encryption for your API.
We also saw that HTTPS is normally provided by a component **external** to your application server, a **TLS Termination Proxy**.
And there has to be something in charge of **renewing the HTTPS certificates**, it could be the same component or it could be something different.
### Example Tools for HTTPS
Some of the tools you could use as a TLS Termination Proxy are:
* Traefik
* Automatically handles certificates renewals ✨
* Caddy
* Automatically handles certificates renewals ✨
* Nginx
* With an external component like Certbot for certificate renewals
* HAProxy
* With an external component like Certbot for certificate renewals
* Kubernetes with an Ingress Controller like Nginx
* With an external component like cert-manager for certificate renewals
* Handled internally by a cloud provider as part of their services (read below 👇)
Another option is that you could use a **cloud service** that does more of the work including setting up HTTPS. It could have some restrictions or charge you more, etc. But in that case, you wouldn't have to set up a TLS Termination Proxy yourself.
I'll show you some concrete examples in the next chapters.
---
Then the next concepts to consider are all about the program running your actual API (e.g. Uvicorn).
## Program and Process
We will talk a lot about the running "**process**", so it's useful to have clarity about what it means, and what's the difference with the word "**program**".
### What is a Program
The word **program** is commonly used to describe many things:
* The **code** that you write, the **Python files**.
* The **file** that can be **executed** by the operating system, for example: `python`, `python.exe` or `uvicorn`.
* A particular program while it is **running** on the operating system, using the CPU, and storing things on memory. This is also called a **process**.
### What is a Process
The word **process** is normally used in a more specific way, only referring to the thing that is running in the operating system (like in the last point above):
* A particular program while it is **running** on the operating system.
* This doesn't refer to the file, nor to the code, it refers **specifically** to the thing that is being **executed** and managed by the operating system.
* Any program, any code, **can only do things** when it is being **executed**. So, when there's a **process running**.
* The process can be **terminated** (or "killed") by you, or by the operating system. At that point, it stops running/being executed, and it can **no longer do things**.
* Each application that you have running on your computer has some process behind it, each running program, each window, etc. And there are normally many processes running **at the same time** while a computer is on.
* There can be **multiple processes** of the **same program** running at the same time.
If you check out the "task manager" or "system monitor" (or similar tools) in your operating system, you will be able to see many of those processes running.
And, for example, you will probably see that there are multiple processes running the same browser program (Firefox, Chrome, Edge, etc). They normally run one process per tab, plus some other extra processes.
<img class="shadow" src="/img/deployment/concepts/image01.png">
---
Now that we know the difference between the terms **process** and **program**, let's continue talking about deployments.
## Running on Startup
In most cases, when you create a web API, you want it to be **always running**, uninterrupted, so that your clients can always access it. This is of course, unless you have a specific reason why you want it to run only in certain situations, but most of the time you want it constantly running and **available**.
### In a Remote Server
When you set up a remote server (a cloud server, a virtual machine, etc.) the simplest thing you can do is to run Uvicorn (or similar) manually, the same way you do when developing locally.
And it will work and will be useful **during development**.
But if your connection to the server is lost, the **running process** will probably die.
And if the server is restarted (for example after updates, or migrations from the cloud provider) you probably **won't notice it**. And because of that, you won't even know that you have to restart the process manually. So, your API will just stay dead. 😱
### Run Automatically on Startup
In general, you will probably want the server program (e.g. Uvicorn) to be started automatically on server startup, and without needing any **human intervention**, to have a process always running with your API (e.g. Uvicorn running your FastAPI app).
### Separate Program
To achieve this, you will normally have a **separate program** that would make sure your application is run on startup. And in many cases, it would also make sure other components or applications are also run, for example, a database.
### Example Tools to Run at Startup
Some examples of the tools that can do this job are:
* Docker
* Kubernetes
* Docker Compose
* Docker in Swarm Mode
* Systemd
* Supervisor
* Handled internally by a cloud provider as part of their services
* Others...
I'll give you more concrete examples in the next chapters.
## Restarts
Similar to making sure your application is run on startup, you probably also want to make sure it is **restarted** after failures.
### We Make Mistakes
We, as humans, make **mistakes**, all the time. Software almost *always* has **bugs** hidden in different places. 🐛
And we as developers keep improving the code as we find those bugs and as we implement new features (possibly adding new bugs too 😅).
### Small Errors Automatically Handled
When building web APIs with FastAPI, if there's an error in our code, FastAPI will normally contain it to the single request that triggered the error. 🛡
The client will get a **500 Internal Server Error** for that request, but the application will continue working for the next requests instead of just crashing completely.
### Bigger Errors - Crashes
Nevertheless, there might be cases where we write some code that **crashes the entire application** making Uvicorn and Python crash. 💥
And still, you would probably not want the application to stay dead because there was an error in one place, you probably want it to **continue running** at least for the *path operations* that are not broken.
### Restart After Crash
But in those cases with really bad errors that crash the running **process**, you would want an external component that is in charge of **restarting** the process, at least a couple of times...
!!! tip
...Although if the whole application is just **crashing immediately** it probably doesn't make sense to keep restarting it forever. But in those cases, you will probably notice it during development, or at least right after deployment.
So let's focus on the main cases, where it could crash entirely in some particular cases **in the future**, and it still makes sense to restart it.
You would probably want to have the thing in charge of restarting your application as an **external component**, because by that point, the same application with Uvicorn and Python already crashed, so there's nothing in the same code of the same app that could do anything about it.
### Example Tools to Restart Automatically
In most cases, the same tool that is used to **run the program on startup** is also used to handle automatic **restarts**.
For example, this could be handled by:
* Docker
* Kubernetes
* Docker Compose
* Docker in Swarm Mode
* Systemd
* Supervisor
* Handled internally by a cloud provider as part of their services
* Others...
## Replication - Processes and Memory
With a FastAPI application, using a server program like Uvicorn, running it once in **one process** can serve multiple clients concurrently.
But in many cases, you will want to run several worker processes at the same time.
### Multiple Processes - Workers
If you have more clients than what a single process can handle (for example if the virtual machine is not too big) and you have **multiple cores** in the server's CPU, then you could have **multiple processes** running with the same application at the same time, and distribute all the requests among them.
When you run **multiple processes** of the same API program, they are commonly called **workers**.
### Worker Processes and Ports
Remember from the docs [About HTTPS](./https.md){.internal-link target=_blank} that only one process can be listening on one combination of port and IP address in a server?
This is still true.
So, to be able to have **multiple processes** at the same time, there has to be a **single process listening on a port** that then transmits the communication to each worker process in some way.
### Memory per Process
Now, when the program loads things in memory, for example, a machine learning model in a variable, or the contents of a large file in a variable, all that **consumes a bit of the memory (RAM)** of the server.
And multiple processes normally **don't share any memory**. This means that each running process has its own things, variables, and memory. And if you are consuming a large amount of memory in your code, **each process** will consume an equivalent amount of memory.
### Server Memory
For example, if your code loads a Machine Learning model with **1 GB in size**, when you run one process with your API, it will consume at least 1 GB of RAM. And if you start **4 processes** (4 workers), each will consume 1 GB of RAM. So in total, your API will consume **4 GB of RAM**.
And if your remote server or virtual machine only has 3 GB of RAM, trying to load more than 4 GB of RAM will cause problems. 🚨
### Multiple Processes - An Example
In this example, there's a **Manager Process** that starts and controls two **Worker Processes**.
This Manager Process would probably be the one listening on the **port** in the IP. And it would transmit all the communication to the worker processes.
Those worker processes would be the ones running your application, they would perform the main computations to receive a **request** and return a **response**, and they would load anything you put in variables in RAM.
<img src="/img/deployment/concepts/process-ram.svg">
And of course, the same machine would probably have **other processes** running as well, apart from your application.
An interesting detail is that the percentage of the **CPU used** by each process can **vary** a lot over time, but the **memory (RAM)** normally stays more or less **stable**.
If you have an API that does a comparable amount of computations every time and you have a lot of clients, then the **CPU utilization** will probably *also be stable* (instead of constantly going up and down quickly).
### Examples of Replication Tools and Strategies
There can be several approaches to achieve this, and I'll tell you more about specific strategies in the next chapters, for example when talking about Docker and containers.
The main constraint to consider is that there has to be a **single** component handling the **port** in the **public IP**. And then it has to have a way to **transmit** the communication to the replicated **processes/workers**.
Here are some possible combinations and strategies:
* **Gunicorn** managing **Uvicorn workers**
* Gunicorn would be the **process manager** listening on the **IP** and **port**, the replication would be by having **multiple Uvicorn worker processes**
* **Uvicorn** managing **Uvicorn workers**
* One Uvicorn **process manager** would listen on the **IP** and **port**, and it would start **multiple Uvicorn worker processes**
* **Kubernetes** and other distributed **container systems**
* Something in the **Kubernetes** layer would listen on the **IP** and **port**. The replication would be by having **multiple containers**, each with **one Uvicorn process** running
* **Cloud services** that handle this for your
* The cloud service will probably **handle replication for you**. It would possibly let you define **a process to run**, or a **container image** to use, in any case, it would most probably be **a single Uvicorn process**, and the cloud service would be in charge of replicating it.
!!! tip
Don't worry if some of these items about **containers**, Docker, or Kubernetes don't make a lot of sense yet.
I'll tell you more about container images, Docker, Kubernetes, etc. in a future chapter: [FastAPI in Containers - Docker](./docker.md){.internal-link target=_blank}.
## Previous Steps Before Starting
There are many cases where you want to perform some steps **before starting** your application.
For example, you might want to run **database migrations**.
But in most cases, you will want to perform these steps only **once**.
So, you will want to have a **single process** to perform those **previous steps**, before starting the application.
And you will have to make sure that it's a single process running those previous steps *even* if afterwards, you start **multiple processes** (multiple workers) for the application itself. If those steps were run by **multiple processes**, they would **duplicate** the work by running it on **parallel**, and if the steps were something delicate like a database migration, they could cause conflicts with each other.
Of course, there are some cases where there's no problem in running the previous steps multiple times, in that case, it's a lot easier to handle.
!!! tip
Also, have in mind that depending on your setup, in some cases you **might not even need any previous steps** before starting your application.
In that case, you wouldn't have to worry about any of this. 🤷
### Examples of Previous Steps Strategies
This will **depend heavily** on the way you **deploy your system**, and it would probably be connected to the way you start programs, handling restarts, etc.
Here are some possible ideas:
* An "Init Container" in Kubernetes that runs before your app container
* A bash script that runs the previous steps and then starts your application
* You would still need a way to start/restart *that* bash script, detect errors, etc.
!!! tip
I'll give you more concrete examples for doing this with containers in a future chapter: [FastAPI in Containers - Docker](./docker.md){.internal-link target=_blank}.
## Resource Utilization
Your server(s) is (are) a **resource**, you can consume or **utilize**, with your programs, the computation time on the CPUs, and the RAM memory available.
How much of the system resources do you want to be consuming/utilizing? It might be easy to think "not much", but in reality, you will probably want to consume **as much as possible without crashing**.
If you are paying for 3 servers but you are using only a little bit of their RAM and CPU, you are probably **wasting money** 💸, and probably **wasting server electric power** 🌎, etc.
In that case, it could be better to have only 2 servers and use a higher percentage of their resources (CPU, memory, disk, network bandwidth, etc).
On the other hand, if you have 2 servers and you are using **100% of their CPU and RAM**, at some point one process will ask for more memory, and the server will have to use the disk as "memory" (which can be thousands of times slower), or even **crash**. Or one process might need to do some computation and would have to wait until the CPU is free again.
In this case, it would be better to get **one extra server** and run some processes on it so that they all have **enough RAM and CPU time**.
There's also the chance that for some reason you have a **spike** of usage of your API. Maybe it went viral, or maybe some other services or bots start using it. And you might want to have extra resources to be safe in those cases.
You could put an **arbitrary number** to target, for example, something **between 50% to 90%** of resource utilization. The point is that those are probably the main things you will want to measure and use to tweak your deployments.
You can use simple tools like `htop` to see the CPU and RAM used in your server or the amount used by each process. Or you can use more complex monitoring tools, which may be distributed across servers, etc.
## Recap
You have been reading here some of the main concepts that you would probably need to have in mind when deciding how to deploy your application:
* Security - HTTPS
* Running on startup
* Restarts
* Replication (the number of processes running)
* Memory
* Previous steps before starting
Understanding these ideas and how to apply them should give you the intuition necessary to take any decisions when configuring and tweaking your deployments. 🤓
In the next sections, I'll give you more concrete examples of possible strategies you can follow. 🚀

View File

@@ -0,0 +1,258 @@
# Deploy FastAPI on Deta
In this section you will learn how to easily deploy a **FastAPI** application on <a href="https://www.deta.sh/?ref=fastapi" class="external-link" target="_blank">Deta</a> using the free plan. 🎁
It will take you about **10 minutes**.
!!! info
<a href="https://www.deta.sh/?ref=fastapi" class="external-link" target="_blank">Deta</a> is a **FastAPI** sponsor. 🎉
## A basic **FastAPI** app
* Create a directory for your app, for example, `./fastapideta/` and enter into 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>.
## Deployment Concepts
Coming back to the concepts we discussed in [Deployments Concepts](./concepts.md){.internal-link target=_blank}, here's how each of them would be handled with Deta:
* **HTTPS**: Handled by Deta, they will give you a subdomain and handle HTTPS automatically.
* **Running on startup**: Handled by Deta, as part of their service.
* **Restarts**: Handled by Deta, as part of their service.
* **Replication**: Handled by Deta, as part of their service.
* **Memory**: Limit predefined by Deta, you could contact them to increase it.
* **Previous steps before starting**: Not directly supported, you could make it work with their Cron system or additional scripts.
!!! note
Deta is designed to make it easy (and free) to deploy simple applications quickly.
It can simplify several use cases, but at the same time, it doesn't support others, like using external databases (apart from Deta's own NoSQL database system), custom virtual machines, etc.
You can read more details in the <a href="https://docs.deta.sh/docs/micros/about/" class="external-link" target="_blank">Deta docs</a> to see if it's the right choice for you.

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