Compare commits

...

128 Commits

Author SHA1 Message Date
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
228 changed files with 6549 additions and 1071 deletions

View File

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

View File

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

View File

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

View File

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

14
.github/workflows/pr-approvals.yml vendored Normal file
View File

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

5
.gitignore vendored
View File

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

View File

@@ -45,38 +45,44 @@ The key features are:
## 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>
---
"*If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]*"
"_If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]_"
"*We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]*"
"_We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]_"
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> founders - <a href="https://spacy.io" target="_blank">spaCy</a> creators</strong> <a href="https://twitter.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://twitter.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
---
"*We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]*"
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div>
---
## **Typer**, the FastAPI of CLIs
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
@@ -125,6 +131,8 @@ $ pip install uvicorn
* Create a file `main.py` with:
```Python
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@@ -136,7 +144,7 @@ def read_root():
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "q": q}
```
@@ -145,7 +153,9 @@ def read_item(item_id: int, q: str = None):
If your code uses `async` / `await`, use `async def`:
```Python hl_lines="7 12"
```Python hl_lines="9 14"
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@@ -157,7 +167,7 @@ async def read_root():
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str = None):
async def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "q": q}
```
@@ -235,7 +245,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 10 11 12 25 26 27"
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
@@ -245,7 +257,7 @@ app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: bool = None
is_offer: Optional[bool] = None
@app.get("/")
@@ -254,7 +266,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}

View File

@@ -168,7 +168,7 @@ You can use this same `responses` parameter to add different media types for the
For example, you can add an additional media type of `image/png`, declaring that your *path operation* can return a JSON object (with media type `application/json`) or a PNG image:
```Python hl_lines="17 18 19 20 21 22 23 24 28"
```Python hl_lines="19 20 21 22 23 24 28"
{!../../../docs_src/additional_responses/tutorial002.py!}
```
@@ -228,7 +228,7 @@ You can use that technique to re-use some predefined responses in your *path ope
For example:
```Python hl_lines="11 12 13 14 15 24"
```Python hl_lines="13 14 15 16 17 26"
{!../../../docs_src/additional_responses/tutorial004.py!}
```

View File

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

View File

@@ -0,0 +1,281 @@
# 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 that the JSON payload with the OpenAPI schema has the path defined as `/api/v1/app` (behind the proxy) instead of `/app`. For example, something like:
```JSON hl_lines="5"
{
"openapi": "3.0.2",
// More stuff here
"paths": {
"/api/v1/app": {
// 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/vi/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, at `/api/v1/docs`, it works correctly! 🎉
Right as we wanted it. ✔️
This is because FastAPI uses this `root_path` internally to tell the docs UI to use the URL for OpenAPI with the path prefix provided by `root_path`.
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">
## 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

@@ -203,6 +203,21 @@ File responses will include appropriate `Content-Length`, `Last-Modified` and `E
{!../../../docs_src/custom_response/tutorial009.py!}
```
## Default response class
When creating a **FastAPI** class instance or an `APIRouter` you can specify which response class to use by default.
The parameter that defines this is `default_response_class`.
In the example below, **FastAPI** will use `ORJSONResponse` by default, in all *path operations*, instead of `JSONResponse`.
```Python hl_lines="2 4"
{!../../../docs_src/custom_response/tutorial010.py!}
```
!!! tip
You can still override `response_class` in *path operations* as before.
## Additional documentation
You can also declare the media type and many other details in OpenAPI using `responses`: [Additional Responses in OpenAPI](additional-responses.md){.internal-link target=_blank}.

View File

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

View File

@@ -52,15 +52,22 @@ First, write all your **FastAPI** application as normally:
Then, use the same utility function to generate the OpenAPI schema, inside a `custom_openapi()` function:
```Python hl_lines="2 15 16 17 18 19 20"
```Python hl_lines="2 15 16 17 18 19 20 21"
{!../../../docs_src/extending_openapi/tutorial001.py!}
```
!!! tip
The `openapi_prefix` will contain any prefix needed for the generated OpenAPI *path operations*.
FastAPI will automatically use the `root_path` to pass it in the `openapi_prefix`.
But the important thing is that your function should receive that parameter `openapi_prefix` and pass it along.
### 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"
```Python hl_lines="22 23 24"
{!../../../docs_src/extending_openapi/tutorial001.py!}
```
@@ -72,7 +79,7 @@ That way, your application won't have to generate the schema every time a user o
It will be generated only once, and then the same cached schema will be used for the next requests.
```Python hl_lines="13 14 24 25"
```Python hl_lines="13 14 25 26"
{!../../../docs_src/extending_openapi/tutorial001.py!}
```
@@ -80,7 +87,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"
```Python hl_lines="29"
{!../../../docs_src/extending_openapi/tutorial001.py!}
```

View File

@@ -31,7 +31,7 @@ It will have a *path operation* that will receive an `Invoice` body, and a query
This part is pretty normal, most of the code is probably already familiar to you:
```Python hl_lines="8 9 10 11 12 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53"
```Python hl_lines="10 11 12 13 14 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54"
{!../../../docs_src/openapi_callbacks/tutorial001.py!}
```
@@ -92,7 +92,7 @@ Because of that, you need to declare what will be the `default_response_class`,
But as we are never calling `app.include_router(some_router)`, we need to set the `default_response_class` during creation of the `APIRouter`.
```Python hl_lines="3 24"
```Python hl_lines="5 26"
{!../../../docs_src/openapi_callbacks/tutorial001.py!}
```
@@ -105,7 +105,7 @@ It should look just like a normal FastAPI *path operation*:
* It should probably have a declaration of the body it should receive, e.g. `body: InvoiceEvent`.
* And it could also have a declaration of the response it should return, e.g. `response_model=InvoiceEventReceived`.
```Python hl_lines="15 16 17 20 21 27 28 29 30 31"
```Python hl_lines="17 18 19 22 23 29 30 31 32 33"
{!../../../docs_src/openapi_callbacks/tutorial001.py!}
```
@@ -172,7 +172,7 @@ At this point you have the *callback path operation(s)* needed (the one(s) that
Now use the parameter `callbacks` in *your API's path operation decorator* to pass the attribute `.routes` (that's actually just a `list` of routes/*path operations*) from that callback router:
```Python hl_lines="34"
```Python hl_lines="36"
{!../../../docs_src/openapi_callbacks/tutorial001.py!}
```

View File

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

View File

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

View File

@@ -0,0 +1,73 @@
# Sub Applications - Mounts
If you need to have two independent FastAPI applications, with their own independent OpenAPI and their own docs UIs, you can have a main app and "mount" one (or more) sub-application(s).
## Mounting a **FastAPI** application
"Mounting" means adding a completely "independent" application in a specific path, that then takes care of handling everything under that path, with the _path operations_ declared in that sub-application.
### Top-level application
First, create the main, top-level, **FastAPI** application, and its *path operations*:
```Python hl_lines="3 6 7 8"
{!../../../docs_src/sub_applications/tutorial001.py!}
```
### Sub-application
Then, create your sub-application, and its *path operations*.
This sub-application is just another standard FastAPI application, but this is the one that will be "mounted":
```Python hl_lines="11 14 15 16"
{!../../../docs_src/sub_applications/tutorial001.py!}
```
### Mount the sub-application
In your top-level application, `app`, mount the sub-application, `subapi`.
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

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

View File

@@ -51,38 +51,7 @@ In your WebSocket route you can `await` for messages and send messages.
You can receive and send binary, text, and JSON data.
## Using `Depends` and others
In WebSocket endpoints you can import from `fastapi` and use:
* `Depends`
* `Security`
* `Cookie`
* `Header`
* `Path`
* `Query`
They work the same way as for other FastAPI endpoints/*path operations*:
```Python hl_lines="53 54 55 56 57 58 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76"
{!../../../docs_src/websockets/tutorial002.py!}
```
!!! info
In a WebSocket it doesn't really make sense to raise an `HTTPException`. So it's better to close the WebSocket connection directly.
You can use a closing code from the <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1" class="external-link" target="_blank">valid codes defined in the specification</a>.
In the future, there will be a `WebSocketException` that you will be able to `raise` from anywhere, and add exception handlers for it. It depends on the <a href="https://github.com/encode/starlette/pull/527" class="external-link" target="_blank">PR #527</a> in Starlette.
## More info
To learn more about the options, check Starlette's documentation for:
* <a href="https://www.starlette.io/websockets/" class="external-link" target="_blank">The `WebSocket` class</a>.
* <a href="https://www.starlette.io/endpoints/#websocketendpoint" class="external-link" target="_blank">Class-based WebSocket handling</a>.
## Test it
## Try it
If your file is named `main.py`, run your application with:
@@ -115,3 +84,62 @@ 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 59 60 61 62 63 64 65 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 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">
## More info
To learn more about the options, check Starlette's documentation for:
* <a href="https://www.starlette.io/websockets/" class="external-link" target="_blank">The `WebSocket` class</a>.
* <a href="https://www.starlette.io/endpoints/#websocketendpoint" class="external-link" target="_blank">Class-based WebSocket handling</a>.

View File

@@ -1,6 +1,6 @@
# Including WSGI - Flask, Django, others
You can mount WSGI applications as you saw with [Sub Applications - Behind a Proxy, Mounts](./sub-applications-proxy.md){.internal-link target=_blank}.
You can mount WSGI applications as you saw with [Sub Applications - Mounts](./sub-applications.md){.internal-link target=_blank}, [Behind a Proxy](./behind-a-proxy.md){.internal-link target=_blank}.
For that, you can use the `WSGIMiddleware` and use it to wrap your WSGI application, for example, Flask, Django, etc.

View File

@@ -11,3 +11,8 @@ a.internal-link::after {
*/
content: "\00A0↪";
}
/* Give space to lower icons so Gitter chat doesn't get on top of them */
.md-footer-meta {
padding-bottom: 2em;
}

View File

@@ -161,6 +161,8 @@ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
* Create a `main.py` file with:
```Python
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@@ -172,7 +174,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}
```

View File

@@ -25,8 +25,6 @@ Here's an incomplete list of some of them.
* <a href="https://medium.com/data-rebels/fastapi-authentication-revisited-enabling-api-key-authentication-122dc5975680" class="external-link" target="_blank">FastAPI authentication revisited: Enabling API key authentication</a> by <a href="https://medium.com/@nils_29588" class="external-link" target="_blank">Nils de Bruin</a>.
* <a href="https://blog.bartab.fr/fastapi-logging-on-the-fly/" class="external-link" target="_blank">FastAPI, a simple use case on logging</a> by <a href="https://blog.bartab.fr/" class="external-link" target="_blank">@euri10</a>.
* <a href="https://medium.com/@nico.axtmann95/deploying-a-scikit-learn-model-with-onnx-und-fastapi-1af398268915" class="external-link" target="_blank">Deploying a scikit-learn model with ONNX and FastAPI</a> by <a href="https://www.linkedin.com/in/nico-axtmann" class="external-link" target="_blank">Nico Axtmann</a>.
* <a href="https://geekflare.com/python-asynchronous-web-frameworks/" class="external-link" target="_blank">Top 5 Asynchronous Web Frameworks for Python</a> by <a href="https://geekflare.com/author/ankush/" class="external-link" target="_blank">Ankush Thakur</a> on <a href="https://geekflare.com" class="external-link" target="_blank">GeekFlare</a>.
@@ -61,6 +59,23 @@ Here's an incomplete list of some of them.
* <a href="https://iwpnd.pw/articles/2020-03/apache-kafka-fastapi-geostream" class="external-link" target="_blank">Apache Kafka producer and consumer with FastAPI and aiokafka</a> by <a href="https://iwpnd.pw" class="external-link" target="_blank">Benjamin Ramser</a>.
* <a href="https://wuilly.com/2019/10/real-time-notifications-with-python-and-postgres/" class="external-link" target="_blank">Real-time Notifications with Python and Postgres</a> by <a href="https://wuilly.com/" class="external-link" target="_blank">Guillermo Cruz</a>.
* <a href="https://dev.to/paurakhsharma/microservice-in-python-using-fastapi-24cc" class="external-link" target="_blank">Microservice in Python using FastAPI</a> by <a href="https://twitter.com/PaurakhSharma" class="external-link" target="_blank">Paurakh Sharma Humagain</a>.
* <a href="https://dev.to/cuongld2/build-simple-api-service-with-python-fastapi-part-1-581o" class="external-link" target="_blank">Build simple API service with Python FastAPI — Part 1</a> by <a href="https://dev.to/cuongld2" class="external-link" target="_blank">cuongld2</a>.
* <a href="https://paulsec.github.io/posts/fastapi_plus_zeit_serverless_fu/" class="external-link" target="_blank">FastAPI + Zeit.co = 🚀
</a> by <a href="https://twitter.com/PaulWebSec" class="external-link" target="_blank">Paul Sec</a>.
* <a href="https://dev.to/tiangolo/build-a-web-api-from-scratch-with-fastapi-the-workshop-2ehe" class="external-link" target="_blank">Build a web API from scratch with FastAPI - the workshop</a> by <a href="https://twitter.com/tiangolo" class="external-link" target="_blank">Sebastián Ramírez (tiangolo)</a>.
* <a href="https://www.twilio.com/blog/build-secure-twilio-webhook-python-fastapi" class="external-link" target="_blank">Build a Secure Twilio Webhook with Python and FastAPI</a> by <a href="https://www.twilio.com" class="external-link" target="_blank">Twilio</a>.
* <a href="https://www.stavros.io/posts/fastapi-with-django/" class="external-link" target="_blank">Using FastAPI with Django</a> by <a href="https://twitter.com/Stavros" class="external-link" target="_blank">Stavros Korokithakis</a>.
* <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072" class="external-link" target="_blank">Introducing Dispatch</a> by <a href="https://netflixtechblog.com/" class="external-link" target="_blank">Netflix</a>.
### Japanese
* <a href="https://qiita.com/mtitg/items/47770e9a562dd150631d" class="external-link" target="_blank">FastAPIDB接続してCRUDするPython製APIサーバーを構築</a> by <a href="https://qiita.com/mtitg" class="external-link" target="_blank">@mtitg</a>.
@@ -87,12 +102,6 @@ Here's an incomplete list of some of them.
* <a href="https://qiita.com/bee2/items/75d9c0d7ba20e7a4a0e9" class="external-link" target="_blank">[FastAPI] Python製のASGI Web フレームワーク FastAPIに入門する</a> by <a href="https://qiita.com/bee2" class="external-link" target="_blank">@bee2</a>.
### Chinese
* <a href="https://cloud.tencent.com/developer/article/1431448" class="external-link" target="_blank">使用FastAPI框架快速构建高性能的api服务</a> by <a href="https://cloud.tencent.com/developer/user/5471722" class="external-link" target="_blank">逍遥散人</a>.
* <a href="https://wxq0309.github.io/" class="external-link" target="_blank">FastAPI框架中文文档</a> by <a href="https://wxq0309.github.io/" class="external-link" target="_blank">何大仙</a>.
### Vietnamese
* <a href="https://fullstackstation.com/fastapi-trien-khai-bang-docker/" class="external-link" target="_blank">FASTAPI: TRIỂN KHAI BẰNG DOCKER</a> by <a href="https://fullstackstation.com/author/figonking/" class="external-link" target="_blank">Nguyễn Nhân</a>.
@@ -110,11 +119,16 @@ Here's an incomplete list of some of them.
## Podcasts
* <a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" class="external-link" target="_blank">FastAPI on PythonBytes</a> by <a href="https://pythonbytes.fm/" class="external-link" target="_blank">Python Bytes FM</a>.
* <a href="https://www.pythonpodcast.com/fastapi-web-application-framework-episode-259/" class="external-link" target="_blank">Build The Next Generation Of Python Web Applications With FastAPI - Episode 259 - interview to Sebastían Ramírez (tiangolo)</a> by <a href="https://www.pythonpodcast.com/" class="external-link" target="_blank">Podcast.`__init__`</a>.
## Talks
* <a href="https://www.youtube.com/watch?v=3DLwPcrE5mA" class="external-link" target="_blank">PyCon UK 2019: FastAPI from the ground up</a> by <a href="https://twitter.com/chriswithers13" class="external-link" target="_blank">Chris Withers</a>.
* <a href="https://www.youtube.com/watch?v=z9K5pwb0rt8" class="external-link" target="_blank">PyConBY 2020: Serve ML models easily with FastAPI</a> by <a href="https://twitter.com/tiangolo" class="external-link" target="_blank">Sebastián Ramírez (tiangolo)</a>.
* <a href="https://www.youtube.com/watch?v=PnpTY1f4k2U" class="external-link" target="_blank">[VIRTUAL] Py.Amsterdam's flying Software Circus: Intro to FastAPI</a> by <a href="https://twitter.com/tiangolo" class="external-link" target="_blank">Sebastián Ramírez (tiangolo)</a>.
## Projects
Latest GitHub projects with the topic `fastapi`:

View File

@@ -12,28 +12,18 @@ And there are several ways to get help too.
## Star **FastAPI** in GitHub
You can "star" FastAPI in GitHub (clicking the star button at the top right): <a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>.
You can "star" FastAPI in GitHub (clicking the star button at the top right): <a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>. ⭐️
By adding a star, other users will be able to find it more easily and see that it has been already useful for others.
## Watch the GitHub repository for releases
You can "watch" FastAPI in GitHub (clicking the "watch" button at the top right): <a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>.
You can "watch" FastAPI in GitHub (clicking the "watch" button at the top right): <a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>. 👀
There you can select "Releases only".
Doing it, you will receive notifications (in your email) whenever there's a new release (a new version) of **FastAPI** with bug fixes and new features.
## Join the chat
<a href="https://gitter.im/tiangolo/fastapi?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge" target="_blank">
<img src="https://badges.gitter.im/tiangolo/fastapi.svg" alt="Join the chat at https://gitter.im/tiangolo/fastapi">
</a>
Join the chat on Gitter: <a href="https://gitter.im/tiangolo/fastapi" class="external-link" target="_blank">https://gitter.im/tiangolo/fastapi</a>.
There you can ask quick questions, help others, share ideas, etc.
## Connect with the author
You can connect with <a href="https://tiangolo.com" class="external-link" target="_blank">me (Sebastián Ramírez / `tiangolo`)</a>, the author.
@@ -45,39 +35,32 @@ You can:
* Follow me to see when I create a new Open Source project.
* <a href="https://twitter.com/tiangolo" class="external-link" target="_blank">Follow me on **Twitter**</a>.
* Tell me how you use FastAPI (I love to hear that).
* Ask questions.
* Hear when I make announcements or release new tools.
* <a href="https://www.linkedin.com/in/tiangolo/" class="external-link" target="_blank">Connect with me on **Linkedin**</a>.
* Talk to me.
* Endorse me or recommend me :)
* <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">Read what I write (or follow me) on **Medium**</a>.
* Read other ideas, articles and tools I have created.
* Follow me to see when I publish something new.
* Hear when I make announcements or release new tools (although I use Twitter more often 🤷‍♂).
* Read what I write (or follow me) on <a href="https://dev.to/tiangolo" class="external-link" target="_blank">**Dev.to**</a> or <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">**Medium**</a>.
* Read other ideas, articles, and about tools I have created.
* Follow me to read when I publish something new.
## Tweet about **FastAPI**
<a href="https://twitter.com/compose/tweet?text=I'm loving FastAPI because... https://github.com/tiangolo/fastapi cc @tiangolo" class="external-link" target="_blank">Tweet about **FastAPI**</a> and let me and others know why you like it.
## Let me know how are you using **FastAPI**
<a href="https://twitter.com/compose/tweet?text=I'm loving FastAPI because... https://github.com/tiangolo/fastapi cc @tiangolo" class="external-link" target="_blank">Tweet about **FastAPI**</a> and let me and others know why you like it. 🎉
I love to hear about how **FastAPI** is being used, what have you liked in it, in which project/company are you using it, etc.
You can let me know:
* <a href="https://twitter.com/compose/tweet?text=Hey @tiangolo, I'm using FastAPI at..." class="external-link" target="_blank">On **Twitter**</a>.
* <a href="https://www.linkedin.com/in/tiangolo/" class="external-link" target="_blank">On **Linkedin**</a>.
* <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">On **Medium**</a>.
## Vote for FastAPI
* <a href="https://www.slant.co/options/34241/~fastapi-review" class="external-link" target="_blank">Vote for **FastAPI** in Slant</a>.
* <a href="https://alternativeto.net/software/fastapi/" class="external-link" target="_blank">Vote for **FastAPI** in AlternativeTo</a>.
* <a href="https://github.com/marmelab/awesome-rest/pull/93" class="external-link" target="_blank">Vote for **FastAPI** on awesome-rest</a>.
## Help others with issues in GitHub
You can see <a href="https://github.com/tiangolo/fastapi/issues" class="external-link" target="_blank">existing issues</a> and try and help others.
You can see <a href="https://github.com/tiangolo/fastapi/issues" class="external-link" target="_blank">existing issues</a> and try and help others, most of the times they are questions that you might already know the answer for. 🤓
## Watch the GitHub repository
You can "watch" FastAPI in GitHub (clicking the "watch" button at the top right): <a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>.
You can "watch" FastAPI in GitHub (clicking the "watch" button at the top right): <a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>. 👀
If you select "Watching" instead of "Releases only", you will receive notifications when someone creates a new issue.
@@ -87,9 +70,10 @@ Then you can try and help them solving those issues.
You can <a href="https://github.com/tiangolo/fastapi/issues/new/choose" class="external-link" target="_blank">create a new issue</a> in the GitHub repository, for example to:
* Report a bug/issue.
* Ask a question or ask about a problem.
* Suggest a new feature.
* Ask a question.
**Note**: if you create an issue then I'm going to ask you to also help others. 😉
## Create a Pull Request
@@ -100,12 +84,39 @@ You can <a href="https://github.com/tiangolo/fastapi" class="external-link" targ
* To fix an existing issue/bug.
* To add a new feature.
## Join the chat
<a href="https://gitter.im/tiangolo/fastapi?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge" target="_blank">
<img src="https://badges.gitter.im/tiangolo/fastapi.svg" alt="Join the chat at https://gitter.im/tiangolo/fastapi">
</a>
Join the chat on Gitter: <a href="https://gitter.im/tiangolo/fastapi" class="external-link" target="_blank">https://gitter.im/tiangolo/fastapi</a>.
There you can have quick conversations with others, help others, share ideas, etc.
But have in mind that as it allows more "free conversation", it's easy to ask questions that are too general and more difficult to answer, so, you might not receive answers.
In GitHub issues the template will guide to to write the right question so that you can more easily get a good answer, or even solve the problem yourself even before asking. And in GitHub I can make sure I always answer everything, even if it takes some time. I can't personally do that with the Gitter chat. 😅
Conversations in Gitter are also not as easily searchable as in GitHub, so questions and answers might get lost in the conversation.
On the other side, there's more than 1000 people in the chat, so there's a high chance you'll find someone to talk to there, almost all the time. 😄
## Sponsor the author
You can also financially support the author (me) through <a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub sponsors</a>.
There you could buy me a coffee ☕️ to say thanks 😄.
## Sponsor the tools that power FastAPI
As you have seen in the documentation, FastAPI stands on the shoulders of giants, Starlette and Pydantic.
You can also sponsor:
* <a href="https://github.com/sponsors/samuelcolvin" class="external-link" target="_blank">Samuel Colvin (Pydantic)</a>
* <a href="https://github.com/sponsors/encode" class="external-link" target="_blank">Encode (Starlette, Uvicorn)</a>
---
Thanks!
Thanks! 🚀

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 71 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View File

@@ -45,38 +45,44 @@ The key features are:
## 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>
---
"*If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]*"
"_If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]_"
"*We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]*"
"_We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]_"
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> founders - <a href="https://spacy.io" target="_blank">spaCy</a> creators</strong> <a href="https://twitter.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://twitter.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
---
"*We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]*"
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div>
---
## **Typer**, the FastAPI of CLIs
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
@@ -125,6 +131,8 @@ $ pip install uvicorn
* Create a file `main.py` with:
```Python
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@@ -136,7 +144,7 @@ def read_root():
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "q": q}
```
@@ -145,7 +153,9 @@ def read_item(item_id: int, q: str = None):
If your code uses `async` / `await`, use `async def`:
```Python hl_lines="7 12"
```Python hl_lines="9 14"
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@@ -157,7 +167,7 @@ async def read_root():
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str = None):
async def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "q": q}
```
@@ -235,7 +245,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 10 11 12 25 26 27"
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
@@ -245,7 +257,7 @@ app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: bool = None
is_offer: Optional[bool] = None
@app.get("/")
@@ -254,7 +266,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}

View File

@@ -69,3 +69,16 @@ You can read more about it in the docs for the repo.
## Full Stack FastAPI MongoDB
...might come later, depending on my time availability and other factors. 😅 🎉
## Machine Learning models with spaCy and FastAPI
GitHub: <a href="https://github.com/microsoft/cookiecutter-spacy-fastapi" class="external-link" target="_blank">https://github.com/microsoft/cookiecutter-spacy-fastapi</a>
### Machine Learning models with spaCy and FastAPI - Features
* **spaCy** NER model integration.
* **Azure Cognitive Search** request format built in.
* **Production ready** Python web server using Uvicorn and Gunicorn.
* **Azure DevOps** Kubernetes (AKS) CI/CD deployment built in.
* **Multilingual** Easily choose one of spaCy's built in languages during project setup.
* **Easily extensible** to other model frameworks (Pytorch, Tensorflow), not just spaCy.

View File

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

View File

@@ -2,6 +2,106 @@
## Latest changes
## 0.58.1
* Add link in docs to Pydantic data types. PR [#1612](https://github.com/tiangolo/fastapi/pull/1612) by [@tayoogunbiyi](https://github.com/tayoogunbiyi).
* Fix link in warning logs for `openapi_prefix`. PR [#1611](https://github.com/tiangolo/fastapi/pull/1611) by [@bavaria95](https://github.com/bavaria95).
* Fix bad link in docs. PR [#1603](https://github.com/tiangolo/fastapi/pull/1603) by [@molto0504](https://github.com/molto0504).
* Add Vim temporary files to `.gitignore` for contributors using Vim. PR [#1590](https://github.com/tiangolo/fastapi/pull/1590) by [@asheux](https://github.com/asheux).
* Fix typo in docs for sub-applications. PR [#1578](https://github.com/tiangolo/fastapi/pull/1578) by [@schlpbch](https://github.com/schlpbch).
* Use `Optional` in all the examples in the docs. Original PR [#1574](https://github.com/tiangolo/fastapi/pull/1574) by [@chrisngyn](https://github.com/chrisngyn), [@kx-chen](https://github.com/kx-chen), [@YKo20010](https://github.com/YKo20010). Updated and merged PR [#1644](https://github.com/tiangolo/fastapi/pull/1644).
* Update tests and handling of `response_model_by_alias`. PR [#1642](https://github.com/tiangolo/fastapi/pull/1642).
* Add translation to Chinese for [Body - Fields - 请求体 - 字段](https://fastapi.tiangolo.com/zh/tutorial/body-fields/). PR [#1569](https://github.com/tiangolo/fastapi/pull/1569) by [@waynerv](https://github.com/waynerv).
* Update Chinese translation of main page. PR [#1564](https://github.com/tiangolo/fastapi/pull/1564) by [@waynerv](https://github.com/waynerv).
* Add translation to Chinese for [Body - Multiple Parameters - 请求体 - 多个参数](https://fastapi.tiangolo.com/zh/tutorial/body-multiple-params/). PR [#1532](https://github.com/tiangolo/fastapi/pull/1532) by [@waynerv](https://github.com/waynerv).
* Add translation to Chinese for [Path Parameters and Numeric Validations - 路径参数和数值校验](https://fastapi.tiangolo.com/zh/tutorial/path-params-numeric-validations/). PR [#1506](https://github.com/tiangolo/fastapi/pull/1506) by [@waynerv](https://github.com/waynerv).
* Add GitHub action to auto-label approved PRs (mainly for translations). PR [#1638](https://github.com/tiangolo/fastapi/pull/1638).
## 0.58.0
* Deep merge OpenAPI responses to preserve all the additional metadata. PR [#1577](https://github.com/tiangolo/fastapi/pull/1577).
* Mention in docs that only main app events are run (not sub-apps). PR [#1554](https://github.com/tiangolo/fastapi/pull/1554) by [@amacfie](https://github.com/amacfie).
* Fix body validation error response, do not include body variable when it is not embedded. PR [#1553](https://github.com/tiangolo/fastapi/pull/1553) by [@amacfie](https://github.com/amacfie).
* Fix testing OAuth2 security scopes when using dependency overrides. PR [#1549](https://github.com/tiangolo/fastapi/pull/1549) by [@amacfie](https://github.com/amacfie).
* Fix Model for JSON Schema keyword `not` as a JSON Schema instead of a list. PR [#1548](https://github.com/tiangolo/fastapi/pull/1548) by [@v-do](https://github.com/v-do).
* Add support for OpenAPI `servers`. PR [#1547](https://github.com/tiangolo/fastapi/pull/1547) by [@mikaello](https://github.com/mikaello).
## 0.57.0
* Remove broken link from "External Links". PR [#1565](https://github.com/tiangolo/fastapi/pull/1565) by [@victorphoenix3](https://github.com/victorphoenix3).
* Update/fix docs for [WebSockets with dependencies](https://fastapi.tiangolo.com/advanced/websockets/#using-depends-and-others). Original PR [#1540](https://github.com/tiangolo/fastapi/pull/1540) by [@ChihSeanHsu](https://github.com/ChihSeanHsu).
* Add support for Python's `http.HTTPStatus` in `status_code` parameters. PR [#1534](https://github.com/tiangolo/fastapi/pull/1534) by [@retnikt](https://github.com/retnikt).
* When using Pydantic models with `__root__`, use the internal value in `jsonable_encoder`. PR [#1524](https://github.com/tiangolo/fastapi/pull/1524) by [@patrickkwang](https://github.com/patrickkwang).
* Update docs for path parameters. PR [#1521](https://github.com/tiangolo/fastapi/pull/1521) by [@yankeexe](https://github.com/yankeexe).
* Update docs for first steps, links and rewording. PR [#1518](https://github.com/tiangolo/fastapi/pull/1518) by [@yankeexe](https://github.com/yankeexe).
* Enable `showCommonExtensions` in Swagger UI to show additional validations like `maxLength`, etc. PR [#1466](https://github.com/tiangolo/fastapi/pull/1466) by [@TiewKH](https://github.com/TiewKH).
* Make `OAuth2PasswordRequestFormStrict` importable directly from `fastapi.security`. PR [#1462](https://github.com/tiangolo/fastapi/pull/1462) by [@RichardHoekstra](https://github.com/RichardHoekstra).
* Add docs about [Default response class](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class). PR [#1455](https://github.com/tiangolo/fastapi/pull/1455) by [@TezRomacH](https://github.com/TezRomacH).
* Add note in docs about additional parameters `response_model_exclude_defaults` and `response_model_exclude_none` in [Response Model](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). PR [#1427](https://github.com/tiangolo/fastapi/pull/1427) by [@wshayes](https://github.com/wshayes).
* Add note about [PyCharm Pydantic plugin](https://github.com/koxudaxi/pydantic-pycharm-plugin) to docs. PR [#1420](https://github.com/tiangolo/fastapi/pull/1420) by [@koxudaxi](https://github.com/koxudaxi).
* Update and clarify testing function name. PR [#1395](https://github.com/tiangolo/fastapi/pull/1395) by [@chenl](https://github.com/chenl).
* Fix duplicated headers created by indirect dependencies that use the request directly. PR [#1386](https://github.com/tiangolo/fastapi/pull/1386) by [@obataku](https://github.com/obataku) from tests by [@scottsmith2gmail](https://github.com/scottsmith2gmail).
* Upgrade Starlette version to `0.13.4`. PR [#1361](https://github.com/tiangolo/fastapi/pull/1361) by [@rushton](https://github.com/rushton).
* Improve error handling and feedback for requests with invalid JSON. PR [#1354](https://github.com/tiangolo/fastapi/pull/1354) by [@aviramha](https://github.com/aviramha).
* Add support for declaring metadata for tags in OpenAPI. New docs at [Tutorial - Metadata and Docs URLs - Metadata for tags](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-tags). PR [#1348](https://github.com/tiangolo/fastapi/pull/1348) by [@thomas-maschler](https://github.com/thomas-maschler).
* Add basic setup for Russian translations. PR [#1566](https://github.com/tiangolo/fastapi/pull/1566).
* Remove obsolete Chinese articles after adding official community translations. PR [#1510](https://github.com/tiangolo/fastapi/pull/1510) by [@waynerv](https://github.com/waynerv).
* Add `__repr__` for *path operation function* parameter helpers (like `Query`, `Depends`, etc) to simplify debugging. PR [#1560](https://github.com/tiangolo/fastapi/pull/1560) by [@rkbeatss](https://github.com/rkbeatss) and [@victorphoenix3](https://github.com/victorphoenix3).
## 0.56.1
* Add link to advanced docs from tutorial. PR [#1512](https://github.com/tiangolo/fastapi/pull/1512) by [@kx-chen](https://github.com/kx-chen).
* Remove internal unnecessary f-strings. PR [#1526](https://github.com/tiangolo/fastapi/pull/1526) by [@kotamatsuoka](https://github.com/kotamatsuoka).
* Add translation to Chinese for [Query Parameters and String Validations - 查询参数和字符串校验](https://fastapi.tiangolo.com/zh/tutorial/query-params-str-validations/). PR [#1500](https://github.com/tiangolo/fastapi/pull/1500) by [@waynerv](https://github.com/waynerv).
* Add translation to Chinese for [Request Body - 请求体](https://fastapi.tiangolo.com/zh/tutorial/body/). PR [#1492](https://github.com/tiangolo/fastapi/pull/1492) by [@waynerv](https://github.com/waynerv).
* Add translation to Chinese for [Help FastAPI - Get Help - 帮助 FastAPI - 获取帮助](https://fastapi.tiangolo.com/zh/help-fastapi/). PR [#1465](https://github.com/tiangolo/fastapi/pull/1465) by [@waynerv](https://github.com/waynerv).
* Add translation to Chinese for [Query Parameters - 查询参数](https://fastapi.tiangolo.com/zh/tutorial/query-params/). PR [#1454](https://github.com/tiangolo/fastapi/pull/1454) by [@waynerv](https://github.com/waynerv).
* Add translation to Chinese for [Contributing - 开发 - 贡献](https://fastapi.tiangolo.com/zh/contributing/). PR [#1460](https://github.com/tiangolo/fastapi/pull/1460) by [@waynerv](https://github.com/waynerv).
* Add translation to Chinese for [Path Parameters - 路径参数](https://fastapi.tiangolo.com/zh/tutorial/path-params/). PR [#1453](https://github.com/tiangolo/fastapi/pull/1453) by [@waynerv](https://github.com/waynerv).
* Add official Microsoft project generator for [serving spaCy with FastAPI and Azure Cognitive Skills](https://github.com/microsoft/cookiecutter-spacy-fastapi) to [Project Generators](https://fastapi.tiangolo.com/project-generation/). PR [#1390](https://github.com/tiangolo/fastapi/pull/1390) by [@kabirkhan](https://github.com/kabirkhan).
* Update docs in [Python Types Intro](https://fastapi.tiangolo.com/python-types/) to include info about `Optional`. Original PR [#1377](https://github.com/tiangolo/fastapi/pull/1377) by [@yaegassy](https://github.com/yaegassy).
* Fix support for callable class dependencies with `yield`. PR [#1365](https://github.com/tiangolo/fastapi/pull/1365) by [@mrosales](https://github.com/mrosales).
* Fix/remove incorrect error logging when a client sends invalid payloads. PR [#1351](https://github.com/tiangolo/fastapi/pull/1351) by [@dbanty](https://github.com/dbanty).
* Add translation to Chinese for [First Steps - 第一步](https://fastapi.tiangolo.com/zh/tutorial/first-steps/). PR [#1323](https://github.com/tiangolo/fastapi/pull/1323) by [@waynerv](https://github.com/waynerv).
* Fix generating OpenAPI for apps using callbacks with routers including Pydantic models. PR [#1322](https://github.com/tiangolo/fastapi/pull/1322) by [@nsidnev](https://github.com/nsidnev).
* Optimize internal regex performance in `get_path_param_names()`. PR [#1243](https://github.com/tiangolo/fastapi/pull/1243) by [@heckad](https://github.com/heckad).
* Remove `*,` from functions in docs where it's not needed. PR [#1239](https://github.com/tiangolo/fastapi/pull/1239) by [@pankaj-giri](https://github.com/pankaj-giri).
* Start translations for Italian. PR [#1557](https://github.com/tiangolo/fastapi/pull/1557) by [@csr](https://github.com/csr).
## 0.56.0
* Add support for ASGI `root_path`:
* Use `root_path` internally for mounted applications, so that OpenAPI and the docs UI works automatically without extra configurations and parameters.
* Add new `root_path` parameter for `FastAPI` applications to provide it in cases where it can be set with the command line (e.g. for Uvicorn and Hypercorn, with the parameter `--root-path`).
* Deprecate `openapi_prefix` parameter in favor of the new `root_path` parameter.
* Add new/updated docs for [Sub Applications - Mounts](https://fastapi.tiangolo.com/advanced/sub-applications/), without `openapi_prefix` (as it is now handled automatically).
* Add new/updated docs for [Behind a Proxy](https://fastapi.tiangolo.com/advanced/behind-a-proxy/), including how to setup a local testing proxy with Traefik and using `root_path`.
* Update docs for [Extending OpenAPI](https://fastapi.tiangolo.com/advanced/extending-openapi/) with the new `openapi_prefix` parameter passed (internally generated from `root_path`).
* Original PR [#1199](https://github.com/tiangolo/fastapi/pull/1199) by [@iksteen](https://github.com/iksteen).
* Update new issue templates and docs: [Help FastAPI - Get Help](https://fastapi.tiangolo.com/help-fastapi/). PR [#1531](https://github.com/tiangolo/fastapi/pull/1531).
* Update GitHub action issue-manager. PR [#1520](https://github.com/tiangolo/fastapi/pull/1520).
* Add new links:
* **English articles**:
* [Real-time Notifications with Python and Postgres](https://wuilly.com/2019/10/real-time-notifications-with-python-and-postgres/) by [Guillermo Cruz](https://wuilly.com/).
* [Microservice in Python using FastAPI](https://dev.to/paurakhsharma/microservice-in-python-using-fastapi-24cc) by [Paurakh Sharma Humagain](https://twitter.com/PaurakhSharma).
* [Build simple API service with Python FastAPI — Part 1](https://dev.to/cuongld2/build-simple-api-service-with-python-fastapi-part-1-581o) by [cuongld2](https://dev.to/cuongld2).
* [FastAPI + Zeit.co = 🚀](https://paulsec.github.io/posts/fastapi_plus_zeit_serverless_fu/) by [Paul Sec](https://twitter.com/PaulWebSec).
* [Build a web API from scratch with FastAPI - the workshop](https://dev.to/tiangolo/build-a-web-api-from-scratch-with-fastapi-the-workshop-2ehe) by [Sebastián Ramírez (tiangolo)](https://twitter.com/tiangolo).
* [Build a Secure Twilio Webhook with Python and FastAPI](https://www.twilio.com/blog/build-secure-twilio-webhook-python-fastapi) by [Twilio](https://www.twilio.com).
* [Using FastAPI with Django](https://www.stavros.io/posts/fastapi-with-django/) by [Stavros Korokithakis](https://twitter.com/Stavros).
* [Introducing Dispatch](https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072) by [Netflix](https://netflixtechblog.com/).
* **Podcasts**:
* [Build The Next Generation Of Python Web Applications With FastAPI - Episode 259 - interview to Sebastían Ramírez (tiangolo)](https://www.pythonpodcast.com/fastapi-web-application-framework-episode-259/) by [Podcast.`__init__`](https://www.pythonpodcast.com/).
* **Talks**:
* [PyConBY 2020: Serve ML models easily with FastAPI](https://www.youtube.com/watch?v=z9K5pwb0rt8) by [Sebastián Ramírez (tiangolo)](https://twitter.com/tiangolo).
* [[VIRTUAL] Py.Amsterdam's flying Software Circus: Intro to FastAPI](https://www.youtube.com/watch?v=PnpTY1f4k2U) by [Sebastián Ramírez (tiangolo)](https://twitter.com/tiangolo).
* PR [#1467](https://github.com/tiangolo/fastapi/pull/1467).
* Add translation to Chinese for [Python Types Intro - Python 类型提示简介](https://fastapi.tiangolo.com/zh/python-types/). PR [#1197](https://github.com/tiangolo/fastapi/pull/1197) by [@waynerv](https://github.com/waynerv).
## 0.55.1
* Fix handling of enums with their own schema in path parameters. To support [samuelcolvin/pydantic#1432](https://github.com/samuelcolvin/pydantic/pull/1432) in FastAPI. PR [#1463](https://github.com/tiangolo/fastapi/pull/1463).
## 0.55.0
* Allow enums to allow them to have their own schemas in OpenAPI. To support [samuelcolvin/pydantic#1432](https://github.com/samuelcolvin/pydantic/pull/1432) in FastAPI. PR [#1461](https://github.com/tiangolo/fastapi/pull/1461).

View File

@@ -57,7 +57,7 @@ Using `BackgroundTasks` also works with the dependency injection system, you can
**FastAPI** knows what to do in each case and how to re-use the same object, so that all the background tasks are merged together and are run in the background afterwards:
```Python hl_lines="11 14 20 23"
```Python hl_lines="13 15 22 25"
{!../../../docs_src/background_tasks/tutorial002.py!}
```

View File

@@ -6,7 +6,7 @@ The same way you can declare additional validation and metadata in *path operati
First, you have to import it:
```Python hl_lines="2"
```Python hl_lines="4"
{!../../../docs_src/body_fields/tutorial001.py!}
```
@@ -17,7 +17,7 @@ First, you have to import it:
You can then use `Field` with model attributes:
```Python hl_lines="9 10"
```Python hl_lines="11 12 13 14"
{!../../../docs_src/body_fields/tutorial001.py!}
```

View File

@@ -8,7 +8,7 @@ First, of course, you can mix `Path`, `Query` and request body parameter declara
And you can also declare body parameters as optional, by setting the default to `None`:
```Python hl_lines="17 18 19"
```Python hl_lines="19 20 21"
{!../../../docs_src/body_multiple_params/tutorial001.py!}
```
@@ -30,7 +30,7 @@ In the previous example, the *path operations* would expect a JSON body with the
But you can also declare multiple body parameters, e.g. `item` and `user`:
```Python hl_lines="20"
```Python hl_lines="22"
{!../../../docs_src/body_multiple_params/tutorial002.py!}
```
@@ -72,7 +72,7 @@ If you declare it as is, because it is a singular value, **FastAPI** will assume
But you can instruct **FastAPI** to treat it as another body key using `Body`:
```Python hl_lines="21"
```Python hl_lines="23"
{!../../../docs_src/body_multiple_params/tutorial003.py!}
```
@@ -104,12 +104,12 @@ Of course, you can also declare additional query parameters whenever you need, a
As, by default, singular values are interpreted as query parameters, you don't have to explicitly add a `Query`, you can just do:
```Python
q: str = None
q: Optional[str] = None
```
as in:
```Python hl_lines="25"
```Python hl_lines="27"
{!../../../docs_src/body_multiple_params/tutorial004.py!}
```
@@ -131,7 +131,7 @@ item: Item = Body(..., embed=True)
as in:
```Python hl_lines="15"
```Python hl_lines="17"
{!../../../docs_src/body_multiple_params/tutorial005.py!}
```

View File

@@ -6,15 +6,15 @@ With **FastAPI**, you can define, validate, document, and use arbitrarily deeply
You can define an attribute to be a subtype. For example, a Python `list`:
```Python hl_lines="12"
```Python hl_lines="14"
{!../../../docs_src/body_nested_models/tutorial001.py!}
```
This will make `tags` be a list of items. Although it doesn't declare the type of each of the items.
## List fields with subtype
## List fields with type parameter
But Python has a specific way to declare lists with subtypes:
But Python has a specific way to declare lists with internal types, or "type parameters":
### Import typing's `List`
@@ -24,12 +24,12 @@ First, import `List` from standard Python's `typing` module:
{!../../../docs_src/body_nested_models/tutorial002.py!}
```
### Declare a `List` with a subtype
### Declare a `List` with a type parameter
To declare types that have subtypes, like `list`, `dict`, `tuple`:
To declare types that have type parameters (internal types), like `list`, `dict`, `tuple`:
* Import them from the `typing` module
* Pass the subtype(s) as "type arguments" using square brackets: `[` and `]`
* Pass the internal type(s) as "type parameters" using square brackets: `[` and `]`
```Python
from typing import List
@@ -39,7 +39,7 @@ my_list: List[str]
That's all standard Python syntax for type declarations.
Use that same standard syntax for model attributes with subtypes.
Use that same standard syntax for model attributes with internal types.
So, in our example, we can make `tags` be specifically a "list of strings":
@@ -71,7 +71,7 @@ Each attribute of a Pydantic model has a type.
But that type can itself be another Pydantic model.
So, you can declare deeply nested JSON `object`s with specific attribute names, types and validations.
So, you can declare deeply nested JSON "objects" with specific attribute names, types and validations.
All that, arbitrarily nested.
@@ -174,7 +174,7 @@ You can define arbitrarily deeply nested models:
```
!!! info
Notice how `Offer` as a list of `Item`s, which in turn have an optional list of `Image`s
Notice how `Offer` has a list of `Item`s, which in turn have an optional list of `Image`s
## Bodies of pure lists

View File

@@ -17,7 +17,7 @@ To declare a **request** body, you use <a href="https://pydantic-docs.helpmanual
First, you need to import `BaseModel` from `pydantic`:
```Python hl_lines="2"
```Python hl_lines="4"
{!../../../docs_src/body/tutorial001.py!}
```
@@ -27,7 +27,7 @@ Then you declare your data model as a class that inherits from `BaseModel`.
Use standard Python types for all the attributes:
```Python hl_lines="5 6 7 8 9"
```Python hl_lines="7 8 9 10 11"
{!../../../docs_src/body/tutorial001.py!}
```
@@ -57,7 +57,7 @@ For example, this model above declares a JSON "`object`" (or Python `dict`) like
To add it to your *path operation*, declare it the same way you declared path and query parameters:
```Python hl_lines="16"
```Python hl_lines="18"
{!../../../docs_src/body/tutorial001.py!}
```
@@ -108,11 +108,22 @@ But you would get the same editor support with <a href="https://www.jetbrains.co
<img src="/img/tutorial/body/image05.png">
!!! tip
If you use <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> as your editor, you can use the <a href="https://github.com/koxudaxi/pydantic-pycharm-plugin/" class="external-link" target="_blank">Pydantic PyCharm Plugin</a>.
It improves editor support for Pydantic models, with:
* auto-completion
* type checks
* refactoring
* searching
* inspections
## Use the model
Inside of the function, you can access all the attributes of the model object directly:
```Python hl_lines="19"
```Python hl_lines="21"
{!../../../docs_src/body/tutorial002.py!}
```
@@ -122,7 +133,7 @@ You can declare path parameters and body requests at the same time.
**FastAPI** will recognize that the function parameters that match path parameters should be **taken from the path**, and that function parameters that are declared to be Pydantic models should be **taken from the request body**.
```Python hl_lines="15 16"
```Python hl_lines="17 18"
{!../../../docs_src/body/tutorial003.py!}
```
@@ -132,7 +143,7 @@ You can also declare **body**, **path** and **query** parameters, all at the sam
**FastAPI** will recognize each of them and take the data from the correct place.
```Python hl_lines="16"
```Python hl_lines="18"
{!../../../docs_src/body/tutorial004.py!}
```
@@ -142,6 +153,11 @@ The function parameters will be recognized as follows:
* If the parameter is of a **singular type** (like `int`, `float`, `str`, `bool`, etc) it will be interpreted as a **query** parameter.
* If the parameter is declared to be of the type of a **Pydantic model**, it will be interpreted as a request **body**.
!!! note
FastAPI will know that the value of `q` is not required because of the default value `= None`.
The `Optional` in `Optional[str]` is not used by FastAPI, but will allow your editor to give you better support and detect errors.
## Without Pydantic
If you don't want to use Pydantic models, you can also use **Body** parameters. See the docs for [Body - Multiple Parameters: Singular values in body](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank}.

View File

@@ -6,7 +6,7 @@ You can define Cookie parameters the same way you define `Query` and `Path` para
First import `Cookie`:
```Python hl_lines="1"
```Python hl_lines="3"
{!../../../docs_src/cookie_params/tutorial001.py!}
```
@@ -16,7 +16,7 @@ Then declare the cookie parameters using the same structure as with `Path` and `
The first value is the default value, you can pass all the extra validation or annotation parameters:
```Python hl_lines="7"
```Python hl_lines="9"
{!../../../docs_src/cookie_params/tutorial001.py!}
```

View File

@@ -6,7 +6,7 @@ Before diving deeper into the **Dependency Injection** system, let's upgrade the
In the previous example, we were returning a `dict` from our dependency ("dependable"):
```Python hl_lines="7"
```Python hl_lines="9"
{!../../../docs_src/dependencies/tutorial001.py!}
```
@@ -71,19 +71,19 @@ That also applies to callables with no parameters at all. The same as it would b
Then, we can change the dependency "dependable" `common_parameters` from above to the class `CommonQueryParameters`:
```Python hl_lines="9 10 11 12 13"
```Python hl_lines="11 12 13 14 15"
{!../../../docs_src/dependencies/tutorial002.py!}
```
Pay attention to the `__init__` method used to create the instance of the class:
```Python hl_lines="10"
```Python hl_lines="12"
{!../../../docs_src/dependencies/tutorial002.py!}
```
...it has the same parameters as our previous `common_parameters`:
```Python hl_lines="6"
```Python hl_lines="8"
{!../../../docs_src/dependencies/tutorial001.py!}
```
@@ -103,7 +103,7 @@ Now you can declare your dependency using this class.
And as when **FastAPI** calls that class the value that will be passed as `commons` to your function will be an "instance" of the class, you can declare that parameter `commons` to be of type of the class, `CommonQueryParams`.
```Python hl_lines="17"
```Python hl_lines="19"
{!../../../docs_src/dependencies/tutorial002.py!}
```
@@ -143,7 +143,7 @@ commons = Depends(CommonQueryParams)
..as in:
```Python hl_lines="17"
```Python hl_lines="19"
{!../../../docs_src/dependencies/tutorial003.py!}
```
@@ -179,7 +179,7 @@ So, you can declare the dependency as the type of the variable, and use `Depends
So, the same example would look like:
```Python hl_lines="17"
```Python hl_lines="19"
{!../../../docs_src/dependencies/tutorial004.py!}
```

View File

@@ -31,7 +31,7 @@ Let's first focus on the dependency.
It is just a function that can take all the same parameters that a *path operation function* can take:
```Python hl_lines="6 7"
```Python hl_lines="8 9"
{!../../../docs_src/dependencies/tutorial001.py!}
```
@@ -55,7 +55,7 @@ And then it just returns a `dict` containing those values.
### Import `Depends`
```Python hl_lines="1"
```Python hl_lines="3"
{!../../../docs_src/dependencies/tutorial001.py!}
```
@@ -63,7 +63,7 @@ And then it just returns a `dict` containing those values.
The same way you use `Body`, `Query`, etc. with your *path operation function* parameters, use `Depends` with a new parameter:
```Python hl_lines="11 16"
```Python hl_lines="13 18"
{!../../../docs_src/dependencies/tutorial001.py!}
```

View File

@@ -10,7 +10,7 @@ They can be as **deep** as you need them to be.
You could create a first dependency ("dependable") like:
```Python hl_lines="6 7"
```Python hl_lines="8 9"
{!../../../docs_src/dependencies/tutorial005.py!}
```
@@ -22,7 +22,7 @@ This is quite simple (not very useful), but will help us focus on how the sub-de
Then you can create another dependency function (a "dependable") that at the same time declares a dependency of its own (so it is a "dependant" too):
```Python hl_lines="11"
```Python hl_lines="13"
{!../../../docs_src/dependencies/tutorial005.py!}
```
@@ -37,7 +37,7 @@ Let's focus on the parameters declared:
Then we can use the dependency with:
```Python hl_lines="19"
```Python hl_lines="21"
{!../../../docs_src/dependencies/tutorial005.py!}
```

View File

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

View File

@@ -49,17 +49,18 @@ Here are some of the additional data types you can use:
* `Decimal`:
* Standard Python `Decimal`.
* In requests and responses, handled the same as a `float`.
* You can check all the valid pydantic data types here: <a href="https://pydantic-docs.helpmanual.io/usage/types" class="external-link" target="_blank">Pydantic data types</a>.
## Example
Here's an example *path operation* with parameters using some of the above types.
```Python hl_lines="1 2 11 12 13 14 15"
```Python hl_lines="1 3 12 13 14 15 16"
{!../../../docs_src/extra_data_types/tutorial001.py!}
```
Note that the parameters inside the function have their natural data type, and you can, for example, perform normal date manipulations, like:
```Python hl_lines="17 18"
```Python hl_lines="18 19"
{!../../../docs_src/extra_data_types/tutorial001.py!}
```

View File

@@ -17,7 +17,7 @@ This is especially the case for user models, because:
Here's a general idea of how the models could look like with their password fields and the places where they are used:
```Python hl_lines="7 9 14 20 22 27 28 31 32 33 38 39"
```Python hl_lines="9 11 16 22 24 29 30 33 34 35 40 41"
{!../../../docs_src/extra_models/tutorial001.py!}
```
@@ -150,7 +150,7 @@ All the data conversion, validation, documentation, etc. will still work as norm
That way, we can declare just the differences between the models (with plaintext `password`, with `hashed_password` and without password):
```Python hl_lines="7 13 14 17 18 21 22"
```Python hl_lines="9 15 16 19 20 23 24"
{!../../../docs_src/extra_models/tutorial002.py!}
```

View File

@@ -71,13 +71,13 @@ You will see the alternative automatic documentation (provided by <a href="https
#### "Schema"
A "schema" is a definition or description of something. Not the code that implements it, but just the abstract description.
A "schema" is a definition or description of something. Not the code that implements it, but just an abstract description.
#### API "schema"
In this case, OpenAPI is a specification that dictates how to define a schema of your API.
In this case, <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> is a specification that dictates how to define a schema of your API.
This OpenAPI schema would include your API paths, the possible parameters they take, etc.
This schema definition includes your API paths, the possible parameters they take, etc.
#### Data "schema"
@@ -91,7 +91,7 @@ OpenAPI defines an API schema for your API. And that schema includes definitions
#### Check the `openapi.json`
If you are curious about how the raw OpenAPI schema looks like, it is just an automatically generated JSON with the descriptions of all your API.
If you are curious about how the raw OpenAPI schema looks like, FastAPI automatically generates a JSON (schema) with the descriptions of all your API.
You can see it directly at: <a href="http://127.0.0.1:8000/openapi.json" class="external-link" target="_blank">http://127.0.0.1:8000/openapi.json</a>.
@@ -120,7 +120,7 @@ It will show a JSON starting with something like:
#### What is OpenAPI for
This OpenAPI schema is what powers the 2 interactive documentation systems included.
The OpenAPI schema is what powers the two interactive documentation systems included.
And there are dozens of alternatives, all based on OpenAPI. You could easily add any of those alternatives to your application built with **FastAPI**.
@@ -139,7 +139,7 @@ You could also use it to generate code automatically, for clients that communica
!!! note "Technical Details"
`FastAPI` is a class that inherits directly from `Starlette`.
You can use all the Starlette functionality with `FastAPI` too.
You can use all the <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> functionality with `FastAPI` too.
### Step 2: create a `FastAPI` "instance"
@@ -202,7 +202,7 @@ https://example.com/items/foo
!!! info
A "path" is also commonly called an "endpoint" or a "route".
Building an API, the "path" is the main way to separate "concerns" and "resources".
While building an API, the "path" is the main way to separate "concerns" and "resources".
#### Operation
@@ -281,7 +281,7 @@ And the more exotic ones:
The information here is presented as a guideline, not a requirement.
For example, when using GraphQL you normally perform all the actions using only `post`.
For example, when using GraphQL you normally perform all the actions using only `POST` operations.
### Step 4: define the **path operation function**
@@ -297,7 +297,7 @@ This is our "**path operation function**":
This is a Python function.
It will be called by **FastAPI** whenever it receives a request to the URL "`/`" using `GET`.
It will be called by **FastAPI** whenever it receives a request to the URL "`/`" using a `GET` operation.
In this case, it is an `async` function.

View File

@@ -209,13 +209,12 @@ Now try sending an invalid item like:
You will receive a response telling you that the data is invalid containing the received body:
```JSON hl_lines="13 14 15 16"
```JSON hl_lines="12 13 14 15"
{
"detail": [
{
"loc": [
"body",
"item",
"size"
],
"msg": "value is not a valid integer",

View File

@@ -6,7 +6,7 @@ You can define Header parameters the same way you define `Query`, `Path` and `Co
First import `Header`:
```Python hl_lines="1"
```Python hl_lines="3"
{!../../../docs_src/header_params/tutorial001.py!}
```
@@ -16,7 +16,7 @@ Then declare the header parameters using the same structure as with `Path`, `Que
The first value is the default value, you can pass all the extra validation or annotation parameters:
```Python hl_lines="7"
```Python hl_lines="9"
{!../../../docs_src/header_params/tutorial001.py!}
```
@@ -44,7 +44,7 @@ So, you can use `user_agent` as you normally would in Python code, instead of ne
If for some reason you need to disable automatic conversion of underscores to hyphens, set the parameter `convert_underscores` of `Header` to `False`:
```Python hl_lines="7"
```Python hl_lines="10"
{!../../../docs_src/header_params/tutorial002.py!}
```

View File

@@ -21,6 +21,58 @@ With this configuration, the automatic API docs would look like:
<img src="/img/tutorial/metadata/image01.png">
## Metadata for tags
You can also add additional metadata for the different tags used to group your path operations with the parameter `openapi_tags`.
It takes a list containing one dictionary for each tag.
Each dictionary can contain:
* `name` (**required**): a `str` with the same tag name you use in the `tags` parameter in your *path operations* and `APIRouter`s.
* `description`: a `str` with a short description for the tag. It can have Markdown and will be shown in the docs UI.
* `externalDocs`: a `dict` describing external documentation with:
* `description`: a `str` with a short description for the external docs.
* `url` (**required**): a `str` with the URL for the external documentation.
### Create metadata for tags
Let's try that in an example with tags for `users` and `items`.
Create metadata for your tags and pass it to the `openapi_tags` parameter:
```Python hl_lines="3 4 5 6 7 8 9 10 11 12 13 14 15 16 18"
{!../../../docs_src/metadata/tutorial004.py!}
```
Notice that you can use Markdown inside of the descriptions, for example "login" will be shown in bold (**login**) and "fancy" will be shown in italics (_fancy_).
!!! tip
You don't have to add metadata for all the tags that you use.
### Use your tags
Use the `tags` parameter with your *path operations* (and `APIRouter`s) to assign them to different tags:
```Python hl_lines="21 26"
{!../../../docs_src/metadata/tutorial004.py!}
```
!!! info
Read more about tags in [Path Operation Configuration](../path-operation-configuration/#tags){.internal-link target=_blank}.
### Check the docs
Now, if you check the docs, they will show all the additional metadata:
<img src="/img/tutorial/metadata/image02.png">
### Order of tags
The order of each tag metadata dictionary also defines the order shown in the docs UI.
For example, even though `users` would go after `items` in alphabetical order, it is shown before them, because we added their metadata as the first dictionary in the list.
## OpenAPI URL
By default, the OpenAPI schema is served at `/openapi.json`.

View File

@@ -6,7 +6,7 @@ The same way you can declare more validations and metadata for query parameters
First, import `Path` from `fastapi`:
```Python hl_lines="1"
```Python hl_lines="3"
{!../../../docs_src/path_params_numeric_validations/tutorial001.py!}
```
@@ -16,7 +16,7 @@ You can declare all the same parameters as for `Query`.
For example, to declare a `title` metadata value for the path parameter `item_id` you can type:
```Python hl_lines="8"
```Python hl_lines="10"
{!../../../docs_src/path_params_numeric_validations/tutorial001.py!}
```

View File

@@ -85,7 +85,7 @@ And when you open your browser at <a href="http://127.0.0.1:8000/docs" class="ex
And because the generated schema is from the <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md" class="external-link" target="_blank">OpenAPI</a> standard, there are many compatible tools.
Because of this, **FastAPI** itself provides an alternative API documentation (using ReDoc):
Because of this, **FastAPI** itself provides an alternative API documentation (using ReDoc), which you can access at <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>:
<img src="/img/tutorial/path-params/image02.png">
@@ -125,7 +125,7 @@ Import `Enum` and create a sub-class that inherits from `str` and from `Enum`.
By inheriting from `str` the API docs will be able to know that the values must be of type `string` and will be able to render correctly.
And create class attributes with fixed values, those fixed values will be the available valid values:
Then create class attributes with fixed values, which will be the available valid values:
```Python hl_lines="1 6 7 8 9"
{!../../../docs_src/path_params/tutorial005.py!}
@@ -147,7 +147,7 @@ Then create a *path parameter* with a type annotation using the enum class you c
### Check the docs
Because the available values for the *path parameter* are specified, the interactive docs can show them nicely:
Because the available values for the *path parameter* are predefined, the interactive docs can show them nicely:
<img src="/img/tutorial/path-params/image03.png">
@@ -167,7 +167,7 @@ You can compare it with the *enumeration member* in your created enum `ModelName
You can get the actual value (a `str` in this case) using `model_name.value`, or in general, `your_enum_member.value`:
```Python hl_lines="19"
```Python hl_lines="20"
{!../../../docs_src/path_params/tutorial005.py!}
```
@@ -178,12 +178,21 @@ You can get the actual value (a `str` in this case) using `model_name.value`, or
You can return *enum members* from your *path operation*, even nested in a JSON body (e.g. a `dict`).
They will be converted to their corresponding values before returning them to the client:
They will be converted to their corresponding values (strings in this case) before returning them to the client:
```Python hl_lines="18 20 21"
```Python hl_lines="18 21 23"
{!../../../docs_src/path_params/tutorial005.py!}
```
In your client you will get a JSON response like:
```JSON
{
"model_name": "alexnet",
"message": "Deep Learning FTW!"
}
```
## Path parameters containing paths
Let's say you have a *path operation* with a path `/files/{file_path}`.

View File

@@ -4,11 +4,16 @@
Let's take this application as example:
```Python hl_lines="7"
```Python hl_lines="9"
{!../../../docs_src/query_params_str_validations/tutorial001.py!}
```
The query parameter `q` is of type `str`, and by default is `None`, so it is optional.
The query parameter `q` is of type `Optional[str]`, that means that it's of type `str` but could also be `None`, and indeed, the default value is `None`, so FastAPI will know it's not required.
!!! note
FastAPI will know that the value of `q` is not required because of the default value `= None`.
The `Optional` in `Optional[str]` is not used by FastAPI, but will allow your editor to give you better support and detect errors.
## Additional validation
@@ -18,7 +23,7 @@ We are going to enforce that even though `q` is optional, whenever it is provide
To achieve that, first import `Query` from `fastapi`:
```Python hl_lines="1"
```Python hl_lines="3"
{!../../../docs_src/query_params_str_validations/tutorial002.py!}
```
@@ -26,7 +31,7 @@ To achieve that, first import `Query` from `fastapi`:
And now use it as the default value of your parameter, setting the parameter `max_length` to 50:
```Python hl_lines="7"
```Python hl_lines="9"
{!../../../docs_src/query_params_str_validations/tutorial002.py!}
```
@@ -35,18 +40,35 @@ As we have to replace the default value `None` with `Query(None)`, the first par
So:
```Python
q: str = Query(None)
q: Optional[str] = Query(None)
```
...makes the parameter optional, the same as:
```Python
q: str = None
q: Optional[str] = None
```
But it declares it explicitly as being a query parameter.
And then, we can pass more parameters to `Query`. In this case, the `max_length` parameter that applies to strings:
!!! info
Have in mind that FastAPI cares about the part:
```Python
= None
```
or the:
```Python
= Query(None)
```
and will use that `None` to detect that the query parameter is not required.
The `Optional` part is only to allow your editor to provide better support.
Then, we can pass more parameters to `Query`. In this case, the `max_length` parameter that applies to strings:
```Python
q: str = Query(None, max_length=50)
@@ -58,7 +80,7 @@ This will validate the data, show a clear error when the data is not valid, and
You can also add a parameter `min_length`:
```Python hl_lines="7"
```Python hl_lines="9"
{!../../../docs_src/query_params_str_validations/tutorial003.py!}
```
@@ -66,7 +88,7 @@ You can also add a parameter `min_length`:
You can define a <abbr title="A regular expression, regex or regexp is a sequence of characters that define a search pattern for strings.">regular expression</abbr> that the parameter should match:
```Python hl_lines="8"
```Python hl_lines="10"
{!../../../docs_src/query_params_str_validations/tutorial004.py!}
```
@@ -104,13 +126,13 @@ q: str
instead of:
```Python
q: str = None
q: Optional[str] = None
```
But we are now declaring it with `Query`, for example like:
```Python
q: str = Query(None, min_length=3)
q: Optional[str] = Query(None, min_length=3)
```
So, when you need to declare a value as required while using `Query`, you can use `...` as the first argument:
@@ -211,13 +233,13 @@ That information will be included in the generated OpenAPI and used by the docum
You can add a `title`:
```Python hl_lines="7"
```Python hl_lines="10"
{!../../../docs_src/query_params_str_validations/tutorial007.py!}
```
And a `description`:
```Python hl_lines="11"
```Python hl_lines="13"
{!../../../docs_src/query_params_str_validations/tutorial008.py!}
```
@@ -239,7 +261,7 @@ But you still need it to be exactly `item-query`...
Then you can declare an `alias`, and that alias is what will be used to find the parameter value:
```Python hl_lines="7"
```Python hl_lines="9"
{!../../../docs_src/query_params_str_validations/tutorial009.py!}
```
@@ -251,7 +273,7 @@ You have to leave it there a while because there are clients using it, but you w
Then pass the parameter `deprecated=True` to `Query`:
```Python hl_lines="16"
```Python hl_lines="18"
{!../../../docs_src/query_params_str_validations/tutorial010.py!}
```

View File

@@ -63,7 +63,7 @@ The parameter values in your function will be:
The same way, you can declare optional query parameters, by setting their default to `None`:
```Python hl_lines="7"
```Python hl_lines="9"
{!../../../docs_src/query_params/tutorial002.py!}
```
@@ -72,11 +72,16 @@ In this case, the function parameter `q` will be optional, and will be `None` by
!!! check
Also notice that **FastAPI** is smart enough to notice that the path parameter `item_id` is a path parameter and `q` is not, so, it's a query parameter.
!!! note
FastAPI will know that `q` is optional because of the `= None`.
The `Optional` in `Optional[str]` is not used by FastAPI (FastAPI will only use the `str` part), but the `Optional[str]` will let your editor help you finding errors in your code.
## Query parameter type conversion
You can also declare `bool` types, and they will be converted:
```Python hl_lines="7"
```Python hl_lines="9"
{!../../../docs_src/query_params/tutorial003.py!}
```
@@ -121,7 +126,7 @@ And you don't have to declare them in any specific order.
They will be detected by name:
```Python hl_lines="6 8"
```Python hl_lines="8 10"
{!../../../docs_src/query_params/tutorial004.py!}
```
@@ -179,7 +184,7 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
And of course, you can define some parameters as required, some as having a default value, and some entirely optional:
```Python hl_lines="7"
```Python hl_lines="10"
{!../../../docs_src/query_params/tutorial006.py!}
```
@@ -191,36 +196,3 @@ In this case, there are 3 query parameters:
!!! tip
You could also use `Enum`s the same way as with [Path Parameters](path-params.md#predefined-values){.internal-link target=_blank}.
## Optional type declarations
!!! warning
This might be an advanced use case.
You might want to skip it.
If you are using `mypy` it could complain with type declarations like:
```Python
limit: int = None
```
With an error like:
```
Incompatible types in assignment (expression has type "None", variable has type "int")
```
In those cases you can use `Optional` to tell `mypy` that the value could be `None`, like:
```Python
from typing import Optional
limit: Optional[int] = None
```
In a *path operation* that could look like:
```Python hl_lines="9"
{!../../../docs_src/query_params/tutorial007.py!}
```

View File

@@ -35,13 +35,13 @@ But most importantly:
Here we are declaring a `UserIn` model, it will contain a plaintext password:
```Python hl_lines="7 9"
```Python hl_lines="9 11"
{!../../../docs_src/response_model/tutorial002.py!}
```
And we are using this model to declare our input and the same model to declare our output:
```Python hl_lines="15 16"
```Python hl_lines="17 18"
{!../../../docs_src/response_model/tutorial002.py!}
```
@@ -58,19 +58,19 @@ But if we use the same model for another *path operation*, we could be sending o
We can instead create an input model with the plaintext password and an output model without it:
```Python hl_lines="7 9 14"
```Python hl_lines="9 11 16"
{!../../../docs_src/response_model/tutorial003.py!}
```
Here, even though our *path operation function* is returning the same input user that contains the password:
```Python hl_lines="22"
```Python hl_lines="24"
{!../../../docs_src/response_model/tutorial003.py!}
```
...we declared the `response_model` to be our model `UserOut`, that doesn't include the password:
```Python hl_lines="20"
```Python hl_lines="22"
{!../../../docs_src/response_model/tutorial003.py!}
```
@@ -94,9 +94,9 @@ Your response model could have default values, like:
{!../../../docs_src/response_model/tutorial004.py!}
```
* `description: str = None` has a default of `None`.
* `description: Optional[str] = None` has a default of `None`.
* `tax: float = 10.5` has a default of `10.5`.
* `tags: List[str] = []` has a default of an empty list: `[]`.
* `tags: List[str] = []` as a default of an empty list: `[]`.
but you might want to omit them from the result if they were not actually stored.
@@ -124,6 +124,14 @@ So, if you send a request to that *path operation* for the item with ID `foo`, t
!!! info
FastAPI uses Pydantic model's `.dict()` with <a href="https://pydantic-docs.helpmanual.io/usage/exporting_models/#modeldict" class="external-link" target="_blank">its `exclude_unset` parameter</a> to achieve this.
!!! info
You can also use:
* `response_model_exclude_defaults=True`
* `response_model_exclude_none=True`
as described in <a href="https://pydantic-docs.helpmanual.io/usage/exporting_models/#modeldict" class="external-link" target="_blank">the Pydantic docs</a> for `exclude_defaults` and `exclude_none`.
#### Data with values for fields with defaults
But if your data has values for the model's fields with default values, like the item with ID `bar`:
@@ -175,7 +183,9 @@ This can be used as a quick shortcut if you have only one Pydantic model and wan
This is because the JSON Schema generated in your app's OpenAPI (and the docs) will still be the one for the complete model, even if you use `response_model_include` or `response_model_exclude` to omit some attributes.
```Python hl_lines="29 35"
This also applies to `response_model_by_alias` that works similarly.
```Python hl_lines="31 37"
{!../../../docs_src/response_model/tutorial005.py!}
```
@@ -188,7 +198,7 @@ This can be used as a quick shortcut if you have only one Pydantic model and wan
If you forget to use a `set` and use a `list` or `tuple` instead, FastAPI will still convert it to a `set` and it will work correctly:
```Python hl_lines="29 35"
```Python hl_lines="31 37"
{!../../../docs_src/response_model/tutorial006.py!}
```

View File

@@ -17,6 +17,9 @@ The same way you can specify a response model, you can also declare the HTTP sta
The `status_code` parameter receives a number with the HTTP status code.
!!! info
`status_code` can alternatively also receive an `IntEnum`, such as Python's <a href="https://docs.python.org/3/library/http.html#http.HTTPStatus" class="external-link" target="_blank">`http.HTTPStatus`</a>.
It will:
* Return that status code in the response.
@@ -83,4 +86,4 @@ They are just a convenience, they hold the same number, but that way you can use
## Changing the default
Later, in the **Advanced User Guide**, you will see how to return a different status code than the default you are declaring here.
Later, in the [Advanced User Guide](../advanced/response-change-status-code.md){.internal-link target=_blank}, you will see how to return a different status code than the default you are declaring here.

View File

@@ -10,7 +10,7 @@ There are several ways you can declare extra JSON Schema information.
You can declare an example for a Pydantic model using `Config` and `schema_extra`, as described in <a href="https://pydantic-docs.helpmanual.io/usage/schema/#schema-customization" class="external-link" target="_blank">Pydantic's docs: Schema customization</a>:
```Python hl_lines="13 14 15 16 17 18 19 20 21"
```Python hl_lines="15 16 17 18 19 20 21 22 23"
{!../../../docs_src/schema_extra_example/tutorial001.py!}
```
@@ -20,7 +20,7 @@ That extra info will be added as-is to the output JSON Schema.
In `Field`, `Path`, `Query`, `Body` and others you'll see later, you can also declare extra info for the JSON Schema by passing any other arbitrary arguments to the function, for example, to add an `example`:
```Python hl_lines="2 8 9 10 11"
```Python hl_lines="4 10 11 12 13"
{!../../../docs_src/schema_extra_example/tutorial002.py!}
```
@@ -33,7 +33,7 @@ The same way you can pass extra info to `Field`, you can do the same with `Path`
For example, you can pass an `example` for a body request to `Body`:
```Python hl_lines="20 21 22 23 24 25"
```Python hl_lines="21 22 23 24 25 26"
{!../../../docs_src/schema_extra_example/tutorial003.py!}
```

View File

@@ -100,7 +100,7 @@ And another utility to verify if a received password matches the hash stored.
And another one to authenticate and return a user.
```Python hl_lines="7 48 55 56 59 60 69 70 71 72 73 74 75"
```Python hl_lines="8 49 56 57 60 61 70 71 72 73 74 75 76"
{!../../../docs_src/security/tutorial004.py!}
```
@@ -135,7 +135,7 @@ Define a Pydantic Model that will be used in the token endpoint for the response
Create a utility function to generate a new access token.
```Python hl_lines="3 6 12 13 14 28 29 30 78 79 80 81 82 83 84 85 86"
```Python hl_lines="4 7 13 14 15 29 30 31 79 80 81 82 83 84 85 86 87"
{!../../../docs_src/security/tutorial004.py!}
```
@@ -147,7 +147,7 @@ Decode the received token, verify it, and return the current user.
If the token is invalid, return an HTTP error right away.
```Python hl_lines="89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106"
```Python hl_lines="90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107"
{!../../../docs_src/security/tutorial004.py!}
```
@@ -157,7 +157,7 @@ Create a `timedelta` with the expiration time of the token.
Create a real JWT access token and return it.
```Python hl_lines="115 116 117 118 119 120 121 122 123 124 125 126 127 128"
```Python hl_lines="116 117 118 119 120 121 122 123 124 125 126 127 128 129"
{!../../../docs_src/security/tutorial004.py!}
```

View File

@@ -49,7 +49,7 @@ Now let's use the utilities provided by **FastAPI** to handle this.
First, import `OAuth2PasswordRequestForm`, and use it as a dependency with `Depends` for the path `/token`:
```Python hl_lines="2 74"
```Python hl_lines="4 76"
{!../../../docs_src/security/tutorial003.py!}
```
@@ -90,7 +90,7 @@ If there is no such user, we return an error saying "incorrect username or passw
For the error, we use the exception `HTTPException`:
```Python hl_lines="1 75 76 77"
```Python hl_lines="3 77 78 79"
{!../../../docs_src/security/tutorial003.py!}
```
@@ -118,7 +118,7 @@ If your database is stolen, the thief won't have your users' plaintext passwords
So, the thief won't be able to try to use those same passwords in another system (as many users use the same password everywhere, this would be dangerous).
```Python hl_lines="78 79 80 81"
```Python hl_lines="80 81 82 83"
{!../../../docs_src/security/tutorial003.py!}
```
@@ -156,7 +156,7 @@ For this simple example, we are going to just be completely insecure and return
But for now, let's focus on the specific details we need.
```Python hl_lines="83"
```Python hl_lines="85"
{!../../../docs_src/security/tutorial003.py!}
```
@@ -181,7 +181,7 @@ Both of these dependencies will just return an HTTP error if the user doesn't ex
So, in our endpoint, we will only get a user if the user exists, was correctly authenticated, and is active:
```Python hl_lines="56 57 58 59 60 61 62 63 64 65 67 68 69 70 88"
```Python hl_lines="58 59 60 61 62 63 64 65 66 67 69 70 71 72 90"
{!../../../docs_src/security/tutorial003.py!}
```

View File

@@ -22,7 +22,9 @@ nav:
- Languages:
- en: /
- es: /es/
- it: /it/
- pt: /pt/
- ru: /ru/
- zh: /zh/
- features.md
- python-types.md
@@ -92,7 +94,8 @@ nav:
- advanced/sql-databases-peewee.md
- advanced/async-sql-databases.md
- advanced/nosql-databases.md
- advanced/sub-applications-proxy.md
- advanced/sub-applications.md
- advanced/behind-a-proxy.md
- advanced/templates.md
- advanced/graphql.md
- advanced/websockets.md

View File

@@ -44,38 +44,44 @@ Sus características principales son:
## Opiniones
"*[...] 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>
---
"*If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]*"
"_If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]_"
"*We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]*"
"_We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]_"
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> founders - <a href="https://spacy.io" target="_blank">spaCy</a> creators</strong> <a href="https://twitter.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://twitter.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
---
"*We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]*"
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div>
---
## **Typer**, el FastAPI de las 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>
@@ -125,6 +131,7 @@ $ pip install uvicorn
```Python
from fastapi import FastAPI
from typing import Optional
app = FastAPI()
@@ -135,7 +142,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}
```
@@ -146,6 +153,7 @@ Si tu código usa `async` / `await`, usa `async def`:
```Python hl_lines="7 12"
from fastapi import FastAPI
from typing import Optional
app = FastAPI()
@@ -156,7 +164,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}
```
@@ -237,6 +245,7 @@ Declara el body usando las declaraciones de tipo estándares de Python gracias a
```Python hl_lines="2 7 8 9 10 23 24 25"
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional
app = FastAPI()
@@ -244,7 +253,7 @@ app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: bool = None
is_offer: Optional[bool] = None
@app.get("/")
@@ -253,7 +262,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}

View File

@@ -22,7 +22,9 @@ nav:
- Languages:
- en: /
- es: /es/
- it: /it/
- pt: /pt/
- ru: /ru/
- zh: /zh/
- features.md
- python-types.md

450
docs/it/docs/index.md Normal file
View File

@@ -0,0 +1,450 @@
{!../../../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://travis-ci.com/tiangolo/fastapi" target="_blank">
<img src="https://travis-ci.com/tiangolo/fastapi.svg?branch=master" alt="Build Status">
</a>
<a href="https://codecov.io/gh/tiangolo/fastapi" target="_blank">
<img src="https://img.shields.io/codecov/c/github/tiangolo/fastapi" alt="Coverage">
</a>
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://badge.fury.io/py/fastapi.svg" alt="Package version">
</a>
<a href="https://gitter.im/tiangolo/fastapi?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge" target="_blank">
<img src="https://badges.gitter.im/tiangolo/fastapi.svg" alt="Join the chat at https://gitter.im/tiangolo/fastapi">
</a>
</p>
---
**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="http://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>
## 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="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>
---
"_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="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 class="termy">
```console
$ pip install uvicorn
---> 100%
```
</div>
## Example
### Create it
* Create a file `main.py` with:
```Python
from fastapi import FastAPI
from typing import Optional
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = Optional[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="7 12"
from fastapi import FastAPI
from typing import Optional
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="2 7 8 9 10 23 24 25"
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional
app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: bool = Optional[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**
* **GraphQL**
* 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="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://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://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.

67
docs/it/mkdocs.yml Normal file
View File

@@ -0,0 +1,67 @@
site_name: FastAPI
site_description: FastAPI framework, high performance, easy to learn, fast to code, ready for production
site_url: https://fastapi.tiangolo.com/it/
theme:
name: material
palette:
primary: teal
accent: amber
icon:
repo: fontawesome/brands/github-alt
logo: https://fastapi.tiangolo.com/img/icon-white.svg
favicon: https://fastapi.tiangolo.com/img/favicon.png
language: it
repo_name: tiangolo/fastapi
repo_url: https://github.com/tiangolo/fastapi
edit_uri: ''
google_analytics:
- UA-133183413-1
- auto
nav:
- FastAPI: index.md
- Languages:
- en: /
- es: /es/
- it: /it/
- pt: /pt/
- ru: /ru/
- zh: /zh/
markdown_extensions:
- toc:
permalink: true
- markdown.extensions.codehilite:
guess_lang: false
- markdown_include.include:
base_path: docs
- admonition
- codehilite
- extra
- pymdownx.superfences:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_div_format ''
- pymdownx.tabbed
extra:
social:
- icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/typer
- icon: fontawesome/brands/twitter
link: https://twitter.com/tiangolo
- 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
extra_css:
- https://fastapi.tiangolo.com/css/termynal.css
- https://fastapi.tiangolo.com/css/custom.css
extra_javascript:
- https://unpkg.com/mermaid@8.4.6/dist/mermaid.min.js
- https://fastapi.tiangolo.com/js/termynal.js
- https://fastapi.tiangolo.com/js/custom.js
- https://fastapi.tiangolo.com/js/chat.js
- https://sidecar.gitter.im/dist/sidecar.v1.js

View File

@@ -124,6 +124,8 @@ $ pip install uvicorn
* Crie um arquivo `main.py` com:
```Python
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@@ -135,7 +137,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}
```
@@ -144,7 +146,9 @@ def read_item(item_id: int, q: str = None):
Se seu código utiliza `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()
@@ -156,7 +160,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}
```
@@ -234,7 +238,7 @@ Agora modifique o arquivo `main.py` para receber um corpo para uma requisição
Declare o corpo utilizando tipos padrão Python, graças ao Pydantic.
```Python hl_lines="2 7 8 9 10 23 24 25"
```Python hl_lines="4 9 10 11 12 25 26 27"
from fastapi import FastAPI
from pydantic import BaseModel
@@ -244,7 +248,7 @@ app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: bool = None
is_offer: Optional[bool] = None
@app.get("/")
@@ -253,7 +257,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}

View File

@@ -22,7 +22,9 @@ nav:
- Languages:
- en: /
- es: /es/
- it: /it/
- pt: /pt/
- ru: /ru/
- zh: /zh/
- features.md
- Tutorial - Guia de Usuário:

453
docs/ru/docs/index.md Normal file
View File

@@ -0,0 +1,453 @@
{!../../../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://travis-ci.com/tiangolo/fastapi" target="_blank">
<img src="https://travis-ci.com/tiangolo/fastapi.svg?branch=master" alt="Build Status">
</a>
<a href="https://codecov.io/gh/tiangolo/fastapi" target="_blank">
<img src="https://img.shields.io/codecov/c/github/tiangolo/fastapi" alt="Coverage">
</a>
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://badge.fury.io/py/fastapi.svg" alt="Package version">
</a>
<a href="https://gitter.im/tiangolo/fastapi?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge" target="_blank">
<img src="https://badges.gitter.im/tiangolo/fastapi.svg" alt="Join the chat at https://gitter.im/tiangolo/fastapi">
</a>
</p>
---
**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="http://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>
## 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="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>
---
"_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="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 class="termy">
```console
$ pip install uvicorn
---> 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 10 11 12 25 26 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**
* **GraphQL**
* 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="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://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://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.

67
docs/ru/mkdocs.yml Normal file
View File

@@ -0,0 +1,67 @@
site_name: FastAPI
site_description: FastAPI framework, high performance, easy to learn, fast to code, ready for production
site_url: https://fastapi.tiangolo.com/ru/
theme:
name: material
palette:
primary: teal
accent: amber
icon:
repo: fontawesome/brands/github-alt
logo: https://fastapi.tiangolo.com/img/icon-white.svg
favicon: https://fastapi.tiangolo.com/img/favicon.png
language: ru
repo_name: tiangolo/fastapi
repo_url: https://github.com/tiangolo/fastapi
edit_uri: ''
google_analytics:
- UA-133183413-1
- auto
nav:
- FastAPI: index.md
- Languages:
- en: /
- es: /es/
- it: /it/
- pt: /pt/
- ru: /ru/
- zh: /zh/
markdown_extensions:
- toc:
permalink: true
- markdown.extensions.codehilite:
guess_lang: false
- markdown_include.include:
base_path: docs
- admonition
- codehilite
- extra
- pymdownx.superfences:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_div_format ''
- pymdownx.tabbed
extra:
social:
- icon: fontawesome/brands/github-alt
link: https://github.com/tiangolo/typer
- icon: fontawesome/brands/twitter
link: https://twitter.com/tiangolo
- 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
extra_css:
- https://fastapi.tiangolo.com/css/termynal.css
- https://fastapi.tiangolo.com/css/custom.css
extra_javascript:
- https://unpkg.com/mermaid@8.4.6/dist/mermaid.min.js
- https://fastapi.tiangolo.com/js/termynal.js
- https://fastapi.tiangolo.com/js/custom.js
- https://fastapi.tiangolo.com/js/chat.js
- https://sidecar.gitter.im/dist/sidecar.v1.js

View File

@@ -0,0 +1,510 @@
# 开发 - 贡献
首先,你最好先了解 [帮助 FastAPI 及获取帮助](help-fastapi.md){.internal-link target=_blank}的基本方式。
## 开发
如果你已经克隆了源码仓库,并且需要深入研究代码,下面是设置开发环境的指南。
### 通过 `venv` 管理虚拟环境
你可以使用 Python 的 `venv` 模块在一个目录中创建虚拟环境:
<div class="termy">
```console
$ python -m venv env
```
</div>
这将使用 Python 程序创建一个 `./env/` 目录,然后你将能够为这个隔离的环境安装软件包。
### 激活虚拟环境
使用以下方法激活新环境:
=== "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>
要检查操作是否成功,运行:
=== "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>
如果显示 `pip` 程序文件位于 `env/bin/pip` 则说明激活成功。 🎉
!!! tip
每一次你在该环境下使用 `pip` 安装了新软件包时,请再次激活该环境。
这样可以确保你在使用由该软件包安装的终端程序(如 `flit`)时使用的是当前虚拟环境中的程序,而不是其他的可能是全局安装的程序。
### Flit
**FastAPI** 使用 <a href="https://flit.readthedocs.io/en/latest/index.html" class="external-link" target="_blank">Flit</a> 来构建、打包和发布项目。
如上所述激活环境后,安装 `flit`
<div class="termy">
```console
$ pip install flit
---> 100%
```
</div>
现在重新激活环境,以确保你正在使用的是刚刚安装的 `flit`(而不是全局环境的)。
然后使用 `flit` 来安装开发依赖:
=== "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>
这将在虚拟环境中安装所有依赖和本地版本的 FastAPI。
#### 使用本地 FastAPI
如果你创建一个导入并使用 FastAPI 的 Python 文件,然后使用虚拟环境中的 Python 运行它,它将使用你本地的 FastAPI 源码。
并且如果你更改该本地 FastAPI 的源码,由于它是通过 `--symlink` (或 Windows 上的 `--pth-file`)安装的,当你再次运行那个 Python 文件,它将使用你刚刚编辑过的最新版本的 FastAPI。
这样,你不必再去重新"安装"你的本地版本即可测试所有更改。
### 格式化
你可以运行下面的脚本来格式化和清理所有代码:
<div class="termy">
```console
$ bash scripts/format.sh
```
</div>
它还会自动对所有导入代码进行整理。
为了使整理正确进行,你需要在当前环境中安装本地的 FastAPI即在运行上述段落中的命令时添加 `--symlink`(或 Windows 上的 `--pth-file`)。
### 格式化导入
还有另一个脚本可以格式化所有导入,并确保你没有未使用的导入代码:
<div class="termy">
```console
$ bash scripts/format-imports.sh
```
</div>
由于它依次运行了多个命令,并修改和还原了许多文件,所以运行时间会更长一些,因此经常地使用 `scripts/format.sh` 然后仅在提交前执行 `scripts/format-imports.sh` 会更好一些。
## 文档
首先,请确保按上述步骤设置好环境,这将安装所有需要的依赖。
文档使用 <a href="https://www.mkdocs.org/" class="external-link" target="_blank">MkDocs</a> 生成。
并且在 `./scripts/docs.py` 中还有适用的额外工具/脚本来处理翻译。
!!! tip
你不需要去了解 `./scripts/docs.py` 中的代码,只需在命令行中使用它即可。
所有文档均在 `./docs/en/` 目录中以 Markdown 文件格式保存。
许多的教程章节里包含有代码块。
在大多数情况下,这些代码块是可以直接运行的真实完整的应用程序。
实际上,这些代码块不是写在 Markdown 文件内的,它们是位于 `./docs_src/` 目录中的 Python 文件。
生成站点时,这些 Python 文件会被包含/注入到文档中。
### 用于测试的文档
大多数的测试实际上都是针对文档中的示例源文件运行的。
这有助于确保:
* 文档始终是最新的。
* 文档示例可以直接运行。
* 绝大多数特性既在文档中得以阐述,又通过测试覆盖进行保障。
在本地开发期间,有一个脚本可以实时重载地构建站点并用来检查所做的任何更改:
<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>
它将在 `http://127.0.0.1:8008` 提供对文档的访问。
这样,你可以编辑文档/源文件并实时查看更改。
#### Typer CLI (可选)
本指引向你展示了如何直接用 `python` 程序运行 `./scripts/docs.py` 中的脚本。
但你也可以使用 <a href="https://typer.tiangolo.com/typer-cli/" class="external-link" target="_blank">Typer CLI</a>,而且在安装了补全功能后,你将可以在终端中对命令进行自动补全。
如果你打算安装 Typer CLI ,可以使用以下命令安装自动补全功能:
<div class="termy">
```console
$ typer --install-completion
zsh completion installed in /home/user/.bashrc.
Completion will take effect once you restart the terminal.
```
</div>
### 应用和文档同时运行
如果你使用以下方式运行示例程序:
<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>
由于 Uvicorn 默认使用 `8000` 端口 ,因此运行在 `8008` 端口上的文档不会与之冲突。
### 翻译
非常感谢你能够参与文档的翻译!这项工作需要社区的帮助才能完成。 🌎 🚀
以下是参与帮助翻译的步骤。
#### 建议和指南
* 在当前 <a href="https://github.com/tiangolo/fastapi/pulls" class="external-link" target="_blank">已有的 pull requests</a> 中查找你使用的语言,添加要求修改或同意合并的评审意见。
!!! tip
你可以为已有的 pull requests <a href="https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request" class="external-link" target="_blank">添加包含修改建议的评论</a>。
详情可查看关于 <a href="https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-request-reviews" class="external-link" target="_blank">添加 pull request 评审意见</a> 以同意合并或要求修改的文档。
* 在 <a href="https://github.com/tiangolo/fastapi/issues" class="external-link" target="_blank">issues</a> 中查找是否有对你所用语言所进行的协作翻译。
* 每翻译一个页面新增一个 pull request。这将使其他人更容易对其进行评审。
对于我(译注:作者使用西班牙语和英语)不懂的语言,我将在等待其他人评审翻译之后将其合并。
* 你还可以查看是否有你所用语言的翻译,并对其进行评审,这将帮助我了解翻译是否正确以及能否将其合并。
* 使用相同的 Python 示例并且仅翻译文档中的文本。无需进行任何其他更改示例也能正常工作。
* 使用相同的图片、文件名以及链接地址。无需进行任何其他调整来让它们兼容。
* 你可以从 <a href="https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes" class="external-link" target="_blank">ISO 639-1 代码列表</a> 表中查找你想要翻译语言的两位字母代码。
#### 已有的语言
假设你想将某个页面翻译成已经翻译了一些页面的语言,例如西班牙语。
对于西班牙语来说,它的两位字母代码是 `es`。所以西班牙语翻译的目录位于 `docs/es/`。
!!! tip
主要("官方")语言是英语,位于 `docs/en/`目录。
现在为西班牙语文档运行实时服务器:
<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>
现在你可以访问 <a href="http://127.0.0.1:8008" class="external-link" target="_blank">http://127.0.0.1:8008</a> 实时查看你所做的更改。
如果你查看 FastAPI 的线上文档网站,会看到每种语言都有所有页面。但是某些页面并未被翻译并且会有一处关于缺少翻译的提示。
但是当你像上面这样在本地运行文档时,你只会看到已经翻译的页面。
现在假设你要为 [Features](features.md){.internal-link target=_blank} 章节添加翻译。
* 复制下面的文件:
```
docs/en/docs/features.md
```
* 粘贴到你想要翻译语言目录的相同位置,比如:
```
docs/es/docs/features.md
```
!!! tip
注意路径和文件名的唯一变化是语言代码,从 `en` 更改为 `es`。
* 现在打开位于英语文档目录下的 MkDocs 配置文件:
```
docs/en/docs/mkdocs.yml
```
* 在配置文件中找到 `docs/features.md` 所在的位置。结果像这样:
```YAML hl_lines="8"
site_name: FastAPI
# More stuff
nav:
- FastAPI: index.md
- Languages:
- en: /
- es: /es/
- features.md
```
* 打开你正在编辑的语言目录中的 MkDocs 配置文件,例如:
```
docs/es/docs/mkdocs.yml
```
* 将其添加到与英语文档完全相同的位置,例如:
```YAML hl_lines="8"
site_name: FastAPI
# More stuff
nav:
- FastAPI: index.md
- Languages:
- en: /
- es: /es/
- features.md
```
如果配置文件中还有其他条目,请确保你所翻译的新条目和它们之间的顺序与英文版本完全相同。
打开浏览器,现在你将看到文档展示了你所加入的新章节。 🎉
现在,你可以将它全部翻译完并在保存文件后进行预览。
#### 新语言
假设你想要为尚未有任何页面被翻译的语言添加翻译。
假设你想要添加克里奥尔语翻译,而且文档中还没有该语言的翻译。
点击上面提到的链接,可以查到"克里奥尔语"的代码为 `ht`。
下一步是运行脚本以生成新的翻译目录:
<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>
现在,你可以在编辑器中查看新创建的目录 `docs/ht/`。
!!! tip
在添加实际的翻译之前,仅以此创建首个 pull request 来设定新语言的配置。
这样当你在翻译第一个页面时,其他人可以帮助翻译其他页面。🚀
首先翻译文档主页 `docs/ht/index.md`。
然后,你可以根据上面的"已有语言"的指引继续进行翻译。
##### 不支持的新语言
如果在运行实时服务器脚本时收到关于不支持该语言的错误,类似于:
```
raise TemplateNotFound(template)
jinja2.exceptions.TemplateNotFound: partials/language/xx.html
```
这意味着文档的主题不支持该语言(在这种例子中,编造的语言代码是 `xx`)。
但是别担心,你可以将主题语言设置为英语,然后翻译文档的内容。
如果你需要这么做,编辑新语言目录下的 `mkdocs.yml`,它将有类似下面的内容:
```YAML hl_lines="5"
site_name: FastAPI
# More stuff
theme:
# More stuff
language: xx
```
将其中的 language 项从 `xx`(你的语言代码)更改为 `en`。
然后,你就可以再次启动实时服务器了。
#### 预览结果
当你通过 `live` 命令使用 `./scripts/docs.py` 中的脚本时,该脚本仅展示当前语言已有的文件和翻译。
但是当你完成翻译后,你可以像在线上展示一样测试所有内容。
为此,首先构建所有文档:
<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>
这将在 `./docs_build/` 目录中为每一种语言生成全部的文档。还包括添加所有缺少翻译的文件,并带有一条"此文件还没有翻译"的提醒。但是你不需要对该目录执行任何操作。
然后,它针对每种语言构建独立的 MkDocs 站点,将它们组合在一起,并在 `./site/` 目录中生成最终的输出。
然后你可以使用命令 `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>
## 测试
你可以在本地运行下面的脚本来测试所有代码并生成 HTML 格式的覆盖率报告:
<div class="termy">
```console
$ bash scripts/test-cov-html.sh
```
</div>
该命令生成了一个 `./htmlcov/` 目录,如果你在浏览器中打开 `./htmlcov/index.html` 文件,你可以交互式地浏览被测试所覆盖的代码区块,并注意是否缺少了任何区块。
### 在编辑器中测试
如果你想要在编辑器中运行集成测试,请将 `./docs_src` 加入到你的 `PYTHONPATH` 变量中。
例如,在 VS Code 中你可以创建一个包含以下内容的 `.env` 文件:
```env
PYTHONPATH=./docs_src
```

View File

@@ -162,6 +162,8 @@ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
* 创建一个 `main.py` 文件,内容如下:
```Python
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@@ -173,7 +175,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}
```

View File

@@ -0,0 +1,111 @@
# 帮助 FastAPI - 获取帮助
你喜欢 **FastAPI** 吗?
您愿意去帮助 FastAPI帮助其他用户以及作者吗
或者你想要获得有关 **FastAPI** 的帮助?
下面是一些非常简单的方式去提供帮助(有些只需单击一两次链接)。
以及几种获取帮助的途径。
## 在 GitHub 上 Star **FastAPI**
你可以在 GitHub 上 "star" FastAPI点击右上角的 star 按钮):<a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>。
通过添加 star其他用户将会更容易发现 FastAPI并了解已经有许多人认为它有用。
## Watch GitHub 仓库的版本发布
你可以在 GitHub 上 "watch" FastAPI点击右上角的 watch 按钮):<a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>。
这时你可以选择 "Releases only" 选项。
之后,只要有 **FastAPI** 的新版本(包含缺陷修复和新功能)发布,你都会(通过电子邮件)收到通知。
## 加入聊天室
<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>
加入 Gitter 上的聊天室:<a href="https://gitter.im/tiangolo/fastapi" class="external-link" target="_blank">https://gitter.im/tiangolo/fastapi</a>。
在这里你可以快速提问、帮助他人、分享想法等。
## 与作者联系
你可以联系 <a href="https://tiangolo.com" class="external-link" target="_blank">我 (Sebastián Ramírez / `tiangolo`)</a> - FastAPI 的作者。
你可以:
* <a href="https://github.com/tiangolo" class="external-link" target="_blank">在 **GitHub** 上关注我</a>。
* 查看我创建的其他的可能对你有帮助的开源项目。
* 关注我以了解我创建的新开源项目。
* <a href="https://twitter.com/tiangolo" class="external-link" target="_blank">在 **Twitter** 上关注我</a>。
* 告诉我你是如何使用 FastAPI 的(我很乐意听到)。
* 提出问题。
* <a href="https://www.linkedin.com/in/tiangolo/" class="external-link" target="_blank">在 **Linkedin** 上联系我</a>。
* 与我交流。
* 认可我的技能或推荐我 :)
* <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">在 **Medium** 上阅读我写的文章(或关注我)</a>。
* 阅读我创建的其他想法,文章和工具。
* 关注我以了解我发布的新内容。
## 发布和 **FastAPI** 有关的推特
<a href="https://twitter.com/compose/tweet?text=I'm loving FastAPI because... https://github.com/tiangolo/fastapi cc @tiangolo" class="external-link" target="_blank"> 发布和 **FastAPI** 有关的推特</a> 让我和其他人知道你为什么喜欢它。
## 告诉我你正在如何使用 **FastAPI**
我很乐意听到有关 **FastAPI** 被如何使用、你喜欢它的哪一点、被投入使用的项目/公司等等信息。
你可以通过以下平台让我知道:
* <a href="https://twitter.com/compose/tweet?text=Hey @tiangolo, I'm using FastAPI at..." class="external-link" target="_blank">**Twitter**</a>。
* <a href="https://www.linkedin.com/in/tiangolo/" class="external-link" target="_blank">**Linkedin**</a>。
* <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">**Medium**</a>。
## 为 FastAPI 投票
* <a href="https://www.slant.co/options/34241/~fastapi-review" class="external-link" target="_blank">在 Slant 上为 **FastAPI** 投票</a>。
## 帮助他人解决 GitHub 的 issues
你可以查看 <a href="https://github.com/tiangolo/fastapi/issues" class="external-link" target="_blank">已有的 issues</a> 并尝试帮助其他人。
## Watch GitHub 仓库
你可以在 GitHub 上 "watch" FastAPI点击右上角的 "watch" 按钮):<a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">https://github.com/tiangolo/fastapi</a>。
如果你选择的是 "Watching" 而不是 "Releases only" 选项,你会在其他人创建了新的 issue 时收到通知。
然后你可以尝试帮助他们解决这些 issue。
## 创建 issue
你可以在 GitHub 仓库中 <a href="https://github.com/tiangolo/fastapi/issues/new/choose" class="external-link" target="_blank">创建一个新 issue</a> 用来:
* 报告 bug 或问题。
* 提议新的特性。
* 提问。
## 创建 Pull Request
你可以 <a href="https://github.com/tiangolo/fastapi" class="external-link" target="_blank">创建一个 Pull Request</a> 用来:
* 纠正你在文档中发现的错别字。
* 添加新的文档内容。
* 修复已有的 bug 或问题。
* 添加新的特性。
## 赞助作者
你还可以通过 <a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub sponsors</a> 在经济上支持作者(我)。
这样你可以给我买杯咖啡☕️以示谢意😄。
---
感谢!

View File

@@ -2,7 +2,7 @@
<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>
<em>FastAPI 框架,高性能,易于学习,高效编码,生产可用</em>
</p>
<p align="center">
<a href="https://travis-ci.com/tiangolo/fastapi" target="_blank">
@@ -27,7 +27,7 @@
---
FastAPI 是一个用于构建 API 的现代、快速(高性能)的 web 框架,使用基于类型提示的 Python 3.6 及更高版本
FastAPI 是一个用于构建 API 的现代、快速(高性能)的 web 框架,使用 Python 3.6+ 并基于标准的 Python 类型提示
关键特性:
@@ -36,54 +36,60 @@ FastAPI 是一个用于构建 API 的现代、快速(高性能)的 web 框
* **高效编码**:提高功能开发速度约 200 至 300。*
* **更少 bug**:减少约 40 的人为(开发者)导致错误。*
* **智能**:极佳的编辑器支持。处处皆可<abbr title="也被称为自动完成、智能感知">自动补全</abbr>,减少调试时间。
* **简单**:设计的易于使用和学习,减少阅读文档时间。
* **简短**减少代码重复。通过不同的参数声明实现丰富功能。bug 更少。
* **健壮**:生产可用级别的代码。以及自动生成的交互式文档。
* **标准化**:基于 API 的相关开放标准并完全兼容<a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (以前被称为 Swagger) 和 <a href="http://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>。
* **简单**:设计的易于使用和学习,阅读文档时间更短
* **简短**使代码重复最小化。通过不同的参数声明实现丰富功能。bug 更少。
* **健壮**:生产可用级别的代码。还有自动生成的交互式文档。
* **标准化**:基于(并完全兼容)API 的相关开放标准:<a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (以前被称为 Swagger) 和 <a href="http://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>。
<small>* 根据对某个构建线上应用的内部开发团队所进行的测试估算得出。</small>
## 评价
"*[...] 最近我一直在使用 **FastAPI**。[...] 实际上我正在计划将其用于我所在的微软团队的所有**机器学习服务**。其中一些服务正被集成进 **Windows** 核心产品和一些 **Office** 产品。*"
「_[...] 最近我一直在使用 **FastAPI**。[...] 实际上我正在计划将其用于我所在的**微软**团队的所有**机器学习服务**。其中一些服务正被集成进核心 **Windows** 产品和一些 **Office** 产品。_」
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>微软</strong> <a href="https://github.com/tiangolo/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div>
---
"***FastAPI** 让我兴奋的欣喜若狂。它太棒了!*"
「_我们选择了 **FastAPI** 来创建用于获取**预测结果**的 **REST** 服务。[用于 Ludwig]_」
<div style="text-align: right; margin-right: 10%;">Piero MolinoYaroslav Dudin 和 Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div>
---
「_**Netflix** 非常高兴地宣布,正式开源我们的**危机管理**编排框架:**Dispatch**[使用 **FastAPI** 构建]_」
<div style="text-align: right; margin-right: 10%;">Kevin GlissonMarc VilanovaForest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072" target="_blank"><small>(ref)</small></a></div>
---
「_**FastAPI** 让我兴奋的欣喜若狂。它太棒了_」
<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> 播客主持人</strong> <a href="https://twitter.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
---
"*老实说,你的作品看起来非常可靠和优美。在很多方面,这就是我想让 **Hug** 成为的样子 - 看到有人实现了它真的很鼓舞人心。*"
「_老实说,你的作品看起来非常可靠和优美。在很多方面,这就是我想让 **Hug** 成为的样子 - 看到有人实现了它真的很鼓舞人心。_」
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="http://www.hug.rest/" target="_blank">Hug</a> 作者</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
---
"*如果你正打算学习一个**现代框架**用来构建 REST API来看下 **FastAPI** [...] 它快速、易用且易于学习 [...]*"
「_如果你正打算学习一个**现代框架**用来构建 REST API来看下 **FastAPI** [...] 它快速、易用且易于学习 [...]_」
"*我们已经将 **API** 服务切换到了 **FastAPI** [...] 我认为你会喜欢它的 [...]*"
「_我们已经将 **API** 服务切换到了 **FastAPI** [...] 我认为你会喜欢它的 [...]_」
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> 创始人 - <a href="https://spacy.io" target="_blank">spaCy</a> 作者</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>
---
"*我们采用了 **FastAPI** 来创建用于获取**预测结果**的 **REST** 服务。[用于 Ludwig]*"
<div style="text-align: right; margin-right: 10%;">Piero Molino Yaroslav Dudin 和 Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div>
---
## **Typer**,命令行中的 Fast API
## **Typer**,命令行中的 FastAPI
<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>
如果你正在开发一个在终端中运行的<abbr title="Command Line Interface">命令行</abbr>应用而不是 web API不妨试下 <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>。
**Typer** 是 FastAPI 的小伙伴。它打算成为**命令行中的 FastAPI**。 ⌨️ 🚀
**Typer** 是 FastAPI 的小同胞。它想要成为**命令行中的 FastAPI**。 ⌨️ 🚀
## 依赖
@@ -91,8 +97,8 @@ Python 3.6 及更高版本
FastAPI 站在以下巨人的肩膀之上:
* <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a>负责 web 部分。
* <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a>负责数据部分。
* <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> 负责 web 部分。
* <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> 负责数据部分。
## 安装
@@ -106,7 +112,7 @@ $ pip install fastapi
</div>
你还需要一个 ASGI 服务器,生产环境可以使用 <a href="http://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> 或者 <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>。
你还需要一个 ASGI 服务器,生产环境可以使用 <a href="http://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> 或者 <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>。
<div class="termy">
@@ -125,6 +131,8 @@ $ pip install uvicorn
* 创建一个 `main.py` 文件并写入以下内容:
```Python
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@@ -136,16 +144,18 @@ 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}
```
<details markdown="1">
<summary>或者使用 <code>async def</code>...</summary>
如果你的代码里会出现 `async` / `await`使用 `async def`
如果你的代码里会出现 `async` / `await`使用 `async def`
```Python hl_lines="9 14"
from typing import Optional
```Python hl_lines="7 12"
from fastapi import FastAPI
app = FastAPI()
@@ -157,7 +167,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}
```
@@ -176,11 +186,11 @@ async def read_item(item_id: int, q: str = None):
```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)
<span style="color: green;">INFO</span>: Started reloader process [28720]
<span style="color: green;">INFO</span>: Started server process [28722]
<span style="color: green;">INFO</span>: Waiting for application startup.
<span style="color: green;">INFO</span>: Application startup complete.
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>
@@ -221,21 +231,23 @@ $ uvicorn main:app --reload
![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
### 备选 API 文档
### 可选的 API 文档
访问 <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>。
你会看到另一个自动生成的文档(由 <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>生成:
你会看到另一个自动生成的文档(由 <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)
## 升级示例
## 示例升级
修改 `main.py` 文件来从 `PUT` 请求中接收请求体。
现在修改 `main.py` 文件来从 `PUT` 请求中接收请求体。
我们借助 Pydantic 来使用标准的 Python 类型声明请求体。
```Python hl_lines="2 7 8 9 10 23 24 25"
```Python hl_lines="4 9 10 11 12 25 26 27"
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
@@ -245,7 +257,7 @@ app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: bool = None
is_offer: Optional[bool] = None
@app.get("/")
@@ -254,7 +266,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}
@@ -265,7 +277,7 @@ def update_item(item_id: int, item: Item):
服务器将会自动重载(因为在上面的步骤中你向 `uvicorn` 命令添加了 `--reload` 选项)。
### 升级交互式 API 文档
### 交互式 API 文档升级
访问 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>。
@@ -273,23 +285,23 @@ def update_item(item_id: int, item: Item):
![Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png)
* 点击 "Try it out" 按钮,之后你可以填写参数并直接调用 API
* 点击Try it out按钮,之后你可以填写参数并直接调用 API
![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-04-swagger-03.png)
* 然后点击 "Execute" 按钮,用户界面将会和 API 进行通信,发送参数,获取结果并在屏幕上展示:
* 然后点击Execute按钮,用户界面将会和 API 进行通信,发送参数,获取结果并在屏幕上展示:
![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-05-swagger-04.png)
### 升级备选文档
### 选文档升级
访问 <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>。
* 选文档同样会体现新加入的请求参数和请求体:
* 选文档同样会体现新加入的请求参数和请求体:
![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png)
### 回顾
### 总结
总的来说,你就像声明函数的参数类型一样只声明了**一次**请求参数、请求体等的类型。
@@ -403,7 +415,6 @@ item: Item
## 性能
独立机构 TechEmpower 所作的基准测试结果显示,基于 Uvicorn 运行的 **FastAPI** 程序是 <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">最快的 Python web 框架之一</a>,仅次于 Starlette 和 Uvicorn 本身FastAPI 内部使用了它们)。(*)
想了解更多,请查阅 <a href="https://fastapi.tiangolo.com/benchmarks/" class="internal-link" target="_blank">基准测试</a> 章节。
@@ -412,7 +423,7 @@ item: Item
用于 Pydantic
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - 更快的 JSON <abbr title="将来自 HTTP 请求中的字符串转换为 Python 数据类型">"解析"</abbr>。
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - 更快的 JSON <abbr title="将来自 HTTP 请求中的字符串转换为 Python 数据类型">解析</abbr>。
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - 用于 email 校验。
用于 Starlette
@@ -420,15 +431,15 @@ item: Item
* <a href="http://docs.python-requests.org" target="_blank"><code>requests</code></a> - 使用 `TestClient` 时安装。
* <a href="https://github.com/Tinche/aiofiles" target="_blank"><code>aiofiles</code></a> - 使用 `FileResponse` 或 `StaticFiles` 时安装。
* <a href="http://jinja.pocoo.org" target="_blank"><code>jinja2</code></a> - 使用默认模板配置时安装。
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - 需要通过 `request.form()` 对表单进行<abbr title="将来自 HTTP 请求中的字符串转换为 Python 数据类型">"解析"</abbr>时安装。
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - 提供 `SessionMiddleware` 支持。
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - 需要通过 `request.form()` 对表单进行<abbr title="将来自 HTTP 请求中的字符串转换为 Python 数据类型">解析</abbr>时安装。
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - 需要 `SessionMiddleware` 支持时安装
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - 使用 Starlette 提供的 `SchemaGenerator` 时安装(有 FastAPI 你可能并不需要它)。
* <a href="https://graphene-python.org/" target="_blank"><code>graphene</code></a> - 需要 `GraphQLApp` 支持时安装。
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - 使用 `UJSONResponse` 时安装。
用于 FastAPI / Starlette
* <a href="http://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - 用于加载和服务你的应用程序的服务器。
* <a href="http://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - 用于加载和运行你的应用程序的服务器。
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - 使用 `ORJSONResponse` 时安装。
你可以通过 `pip install fastapi[all]` 命令来安装以上所有依赖。

View File

@@ -0,0 +1,286 @@
# Python 类型提示简介
**Python 3.6+ 版本**加入了对"类型提示"的支持。
这些**"类型提示"**是一种新的语法(在 Python 3.6 版本加入)用来声明一个变量的<abbr title="例如str、int、float、bool">类型</abbr>。
通过声明变量的类型,编辑器和一些工具能给你提供更好的支持。
这只是一个关于 Python 类型提示的**快速入门 / 复习**。它仅涵盖与 **FastAPI** 一起使用所需的最少部分...实际上只有很少一点。
整个 **FastAPI** 都基于这些类型提示构建,它们带来了许多优点和好处。
但即使你不会用到 **FastAPI**,了解一下类型提示也会让你从中受益。
!!! note
如果你已经精通 Python并且了解关于类型提示的一切知识直接跳到下一章节吧。
## 动机
让我们从一个简单的例子开始:
```Python
{!../../../docs_src/python_types/tutorial001.py!}
```
运行这段程序将输出:
```
John Doe
```
这个函数做了下面这些事情:
* 接收 `first_name``last_name` 参数。
* 通过 `title()` 将每个参数的第一个字母转换为大写形式。
* 中间用一个空格来<abbr title="将它们按顺序放置组合成一个整体。">拼接</abbr>它们。
```Python hl_lines="2"
{!../../../docs_src/python_types/tutorial001.py!}
```
### 修改示例
这是一个非常简单的程序。
现在假设你将从头开始编写这段程序。
在某一时刻,你开始定义函数,并且准备好了参数...。
现在你需要调用一个"将第一个字母转换为大写形式的方法"。
等等,那个方法是什么来着?`upper`?还是 `uppercase``first_uppercase``capitalize`
然后你尝试向程序员老手的朋友——编辑器自动补全寻求帮助。
输入函数的第一个参数 `first_name`,输入点号(`.`)然后敲下 `Ctrl+Space` 来触发代码补全。
但遗憾的是并没有起什么作用:
<img src="https://fastapi.tiangolo.com/img/python-types/image01.png">
### 添加类型
让我们来修改上面例子的一行代码。
我们将把下面这段代码中的函数参数从:
```Python
first_name, last_name
```
改成:
```Python
first_name: str, last_name: str
```
就是这样。
这些就是"类型提示"
```Python hl_lines="1"
{!../../../docs_src/python_types/tutorial002.py!}
```
这和声明默认值是不同的,例如:
```Python
first_name="john", last_name="doe"
```
这两者不一样。
我们用的是冒号(`:`),不是等号(`=`)。
而且添加类型提示一般不会改变原来的运行结果。
现在假设我们又一次正在创建这个函数,这次添加了类型提示。
在同样的地方,通过 `Ctrl+Space` 触发自动补全,你会发现:
<img src="https://fastapi.tiangolo.com/img/python-types/image02.png">
这样,你可以滚动查看选项,直到你找到看起来眼熟的那个:
<img src="https://fastapi.tiangolo.com/img/python-types/image03.png">
## 更多动机
下面是一个已经有类型提示的函数:
```Python hl_lines="1"
{!../../../docs_src/python_types/tutorial003.py!}
```
因为编辑器已经知道了这些变量的类型,所以不仅能对代码进行补全,还能检查其中的错误:
<img src="https://fastapi.tiangolo.com/img/python-types/image04.png">
现在你知道了必须先修复这个问题,通过 `str(age)` 把 `age` 转换成字符串:
```Python hl_lines="2"
{!../../../docs_src/python_types/tutorial004.py!}
```
## 声明类型
你刚刚看到的就是声明类型提示的主要场景。用于函数的参数。
这也是你将在 **FastAPI** 中使用它们的主要场景。
### 简单类型
不只是 `str`,你能够声明所有的标准 Python 类型。
比如以下类型:
* `int`
* `float`
* `bool`
* `bytes`
```Python hl_lines="1"
{!../../../docs_src/python_types/tutorial005.py!}
```
### 嵌套类型
有些容器数据结构可以包含其他的值,比如 `dict`、`list`、`set` 和 `tuple`。它们内部的值也会拥有自己的类型。
你可以使用 Python 的 `typing` 标准库来声明这些类型以及子类型。
它专门用来支持这些类型提示。
#### 列表
例如,让我们来定义一个由 `str` 组成的 `list` 变量。
从 `typing` 模块导入 `List`(注意是大写的 `L`
```Python hl_lines="1"
{!../../../docs_src/python_types/tutorial006.py!}
```
同样以冒号(`:`)来声明这个变量。
输入 `List` 作为类型。
由于列表是带有"子类型"的类型,所以我们把子类型放在方括号中:
```Python hl_lines="4"
{!../../../docs_src/python_types/tutorial006.py!}
```
这表示:"变量 `items` 是一个 `list`,并且这个列表里的每一个元素都是 `str`"。
这样,即使在处理列表中的元素时,你的编辑器也可以提供支持。
没有类型,几乎是不可能实现下面这样:
<img src="https://fastapi.tiangolo.com/img/python-types/image05.png">
注意,变量 `item` 是列表 `items` 中的元素之一。
而且,编辑器仍然知道它是一个 `str`,并为此提供了支持。
#### 元组和集合
声明 `tuple` 和 `set` 的方法也是一样的:
```Python hl_lines="1 4"
{!../../../docs_src/python_types/tutorial007.py!}
```
这表示:
* 变量 `items_t` 是一个 `tuple`,其中的每个元素都是 `int` 类型。
* 变量 `items_s` 是一个 `set`,其中的每个元素都是 `bytes` 类型。
#### 字典
定义 `dict` 时,需要传入两个子类型,用逗号进行分隔。
第一个子类型声明 `dict` 的所有键。
第二个子类型声明 `dict` 的所有值:
```Python hl_lines="1 4"
{!../../../docs_src/python_types/tutorial008.py!}
```
这表示:
* 变量 `prices` 是一个 `dict`
* 这个 `dict` 的所有键为 `str` 类型(可以看作是字典内每个元素的名称)。
* 这个 `dict` 的所有值为 `float` 类型(可以看作是字典内每个元素的价格)。
### 类作为类型
你也可以将类声明为变量的类型。
假设你有一个名为 `Person` 的类,拥有 name 属性:
```Python hl_lines="1 2 3"
{!../../../docs_src/python_types/tutorial009.py!}
```
接下来,你可以将一个变量声明为 `Person` 类型:
```Python hl_lines="6"
{!../../../docs_src/python_types/tutorial009.py!}
```
然后,你将再次获得所有的编辑器支持:
<img src="https://fastapi.tiangolo.com/img/python-types/image06.png">
## Pydantic 模型
<a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> 是一个用来用来执行数据校验的 Python 库。
你可以将数据的"结构"声明为具有属性的类。
每个属性都拥有类型。
接着你用一些值来创建这个类的实例,这些值会被校验,并被转换为适当的类型(在需要的情况下),返回一个包含所有数据的对象。
然后,你将获得这个对象的所有编辑器支持。
下面的例子来自 Pydantic 官方文档:
```Python
{!../../../docs_src/python_types/tutorial010.py!}
```
!!! info
想进一步了解 <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic请阅读其文档</a>.
整个 **FastAPI** 建立在 Pydantic 的基础之上。
实际上你将在 [教程 - 用户指南](tutorial/index.md){.internal-link target=_blank} 看到很多这种情况。
## **FastAPI** 中的类型提示
**FastAPI** 利用这些类型提示来做下面几件事。
使用 **FastAPI** 时用类型提示声明参数可以获得:
* **编辑器支持**。
* **类型检查**。
...并且 **FastAPI** 还会用这些类型声明来:
* **定义参数要求**:声明对请求路径参数、查询参数、请求头、请求体、依赖等的要求。
* **转换数据**:将来自请求的数据转换为需要的类型。
* **校验数据** 对于每一个请求:
* 当数据校验失败时自动生成**错误信息**返回给客户端。
* 使用 OpenAPI **记录** API
* 然后用于自动生成交互式文档的用户界面。
听上去有点抽象。不过不用担心。你将在 [教程 - 用户指南](tutorial/index.md){.internal-link target=_blank} 中看到所有的实战。
最重要的是,通过使用标准的 Python 类型,只需要在一个地方声明(而不是添加更多的类、装饰器等),**FastAPI** 会为你完成很多的工作。
!!! info
如果你已经阅读了所有教程,回过头来想了解有关类型的更多信息,<a href="https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html" class="external-link" target="_blank">来自 `mypy` 的"速查表"</a>是不错的资源。

View File

@@ -0,0 +1,48 @@
# 请求体 - 字段
与使用 `Query``Path``Body` 在*路径操作函数*中声明额外的校验和元数据的方式相同,你可以使用 Pydantic 的 `Field` 在 Pydantic 模型内部声明校验和元数据。
## 导入 `Field`
首先,你必须导入它:
```Python hl_lines="2"
{!../../../docs_src/body_fields/tutorial001.py!}
```
!!! warning
注意,`Field` 是直接从 `pydantic` 导入的,而不是像其他的(`Query``Path``Body` 等)都从 `fastapi` 导入。
## 声明模型属性
然后,你可以对模型属性使用 `Field`
```Python hl_lines="9 10"
{!../../../docs_src/body_fields/tutorial001.py!}
```
`Field` 的工作方式和 `Query`、`Path` 和 `Body` 相同,包括它们的参数等等也完全相同。
!!! note "技术细节"
实际上,`Query`、`Path` 和其他你将在之后看到的类,创建的是由一个共同的 `Params` 类派生的子类的对象,该共同类本身又是 Pydantic 的 `FieldInfo` 类的子类。
Pydantic 的 `Field` 也会返回一个 `FieldInfo` 的实例。
`Body` 也直接返回 `FieldInfo` 的一个子类的对象。还有其他一些你之后会看到的类是 `Body` 类的子类。
请记住当你从 `fastapi` 导入 `Query`、`Path` 等对象时,他们实际上是返回特殊类的函数。
!!! tip
注意每个模型属性如何使用类型、默认值和 `Field` 在代码结构上和*路径操作函数*的参数是相同的,区别是用 `Field` 替换`Path`、`Query` 和 `Body`。
## 添加额外信息
你可以在 `Field`、`Query`、`Body` 中声明额外的信息。这些信息将包含在生成的 JSON Schema 中。
你将在文档的后面部分学习声明示例时,了解到更多有关添加额外信息的知识。
## 总结
你可以使用 Pydantic 的 `Field` 为模型属性声明额外的校验和元数据。
你还可以使用额外的关键字参数来传递额外的 JSON Schema 元数据。

View File

@@ -0,0 +1,170 @@
# 请求体 - 多个参数
既然我们已经知道了如何使用 `Path``Query`,下面让我们来了解一下请求体声明的更高级用法。
## 混合使用 `Path`、`Query` 和请求体参数
首先,毫无疑问地,你可以随意地混合使用 `Path``Query` 和请求体参数声明,**FastAPI** 会知道该如何处理。
你还可以通过将默认值设置为 `None` 来将请求体参数声明为可选参数:
```Python hl_lines="17 18 19"
{!../../../docs_src/body_multiple_params/tutorial001.py!}
```
!!! note
请注意,在这种情况下,将从请求体获取的 `item` 是可选的。因为它的默认值为 `None`。
## 多个请求体参数
在上面的示例中,*路径操作*将期望一个具有 `Item` 的属性的 JSON 请求体,就像:
```JSON
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
}
```
但是你也可以声明多个请求体参数,例如 `item` 和 `user`
```Python hl_lines="20"
{!../../../docs_src/body_multiple_params/tutorial002.py!}
```
在这种情况下,**FastAPI** 将注意到该函数中有多个请求体参数(两个 Pydantic 模型参数)。
因此,它将使用参数名称作为请求体中的键(字段名称),并期望一个类似于以下内容的请求体:
```JSON
{
"item": {
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
},
"user": {
"username": "dave",
"full_name": "Dave Grohl"
}
}
```
!!! note
请注意,即使 `item` 的声明方式与之前相同,但现在它被期望通过 `item` 键内嵌在请求体中。
**FastAPI** 将自动对请求中的数据进行转换,因此 `item` 参数将接收指定的内容,`user` 参数也是如此。
它将执行对复合数据的校验,并且像现在这样为 OpenAPI 模式和自动化文档对其进行记录。
## 请求体中的单一值
与使用 `Query` 和 `Path` 为查询参数和路径参数定义额外数据的方式相同,**FastAPI** 提供了一个同等的 `Body`。
例如,为了扩展先前的模型,你可能决定除了 `item` 和 `user` 之外,还想在同一请求体中具有另一个键 `importance`。
如果你就按原样声明它,因为它是一个单一值,**FastAPI** 将假定它是一个查询参数。
但是你可以使用 `Body` 指示 **FastAPI** 将其作为请求体的另一个键进行处理。
```Python hl_lines="21"
{!../../../docs_src/body_multiple_params/tutorial003.py!}
```
在这种情况下,**FastAPI** 将期望像这样的请求体:
```JSON
{
"item": {
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
},
"user": {
"username": "dave",
"full_name": "Dave Grohl"
},
"importance": 5
}
```
同样的,它将转换数据类型,校验,生成文档等。
## 多个请求体参数和查询参数
当然,除了请求体参数外,你还可以在任何需要的时候声明额外的查询参数。
由于默认情况下单一值被解释为查询参数,因此你不必显式地添加 `Query`,你可以仅执行以下操作:
```Python
q: str = None
```
比如:
```Python hl_lines="25"
{!../../../docs_src/body_multiple_params/tutorial004.py!}
```
!!! info
`Body` 同样具有与 `Query`、`Path` 以及其他后面将看到的类完全相同的额外校验和元数据参数。
## 嵌入单个请求体参数
假设你只有一个来自 Pydantic 模型 `Item` 的请求体参数 `item`。
默认情况下,**FastAPI** 将直接期望这样的请求体。
但是,如果你希望它期望一个拥有 `item` 键并在值中包含模型内容的 JSON就像在声明额外的请求体参数时所做的那样则可以使用一个特殊的 `Body` 参数 `embed`
```Python
item: Item = Body(..., embed=True)
```
比如:
```Python hl_lines="15"
{!../../../docs_src/body_multiple_params/tutorial005.py!}
```
在这种情况下,**FastAPI** 将期望像这样的请求体:
```JSON hl_lines="2"
{
"item": {
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
}
}
```
而不是:
```JSON
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
}
```
## 总结
你可以添加多个请求体参数到*路径操作函数*中,即使一个请求只能有一个请求体。
但是 **FastAPI** 会处理它,在函数中为你提供正确的数据,并在*路径操作*中校验并记录正确的模式。
你还可以声明将作为请求体的一部分所接收的单一值。
你还可以指示 **FastAPI** 在仅声明了一个请求体参数的情况下,将原本的请求体嵌入到一个键中。

View File

@@ -0,0 +1,147 @@
# 请求体
当你需要将数据从客户端(例如浏览器)发送给 API 时,你将其作为「请求体」发送。
**请求**体是客户端发送给 API 的数据。**响应**体是 API 发送给客户端的数据。
你的 API 几乎总是要发送**响应**体。但是客户端并不总是需要发送**请求**体。
我们使用 <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> 模型来声明**请求**体,并能够获得它们所具有的所有能力和优点。
!!! info
你不能使用 `GET` 操作HTTP 方法)发送请求体。
要发送数据,你必须使用下列方法之一:`POST`(较常见)、`PUT``DELETE``PATCH`
## 导入 Pydantic 的 `BaseModel`
首先,你需要从 `pydantic` 中导入 `BaseModel`
```Python hl_lines="2"
{!../../../docs_src/body/tutorial001.py!}
```
## 创建数据模型
然后,将你的数据模型声明为继承自 `BaseModel` 的类。
使用标准的 Python 类型来声明所有属性:
```Python hl_lines="5 6 7 8 9"
{!../../../docs_src/body/tutorial001.py!}
```
和声明查询参数时一样,当一个模型属性具有默认值时,它不是必需的。否则它是一个必需属性。将默认值设为 `None` 可使其成为可选属性。
例如,上面的模型声明了一个这样的 JSON「`object`」(或 Python `dict`
```JSON
{
"name": "Foo",
"description": "An optional description",
"price": 45.2,
"tax": 3.5
}
```
...由于 `description` 和 `tax` 是可选的(它们的默认值为 `None`),下面的 JSON「`object`」也将是有效的:
```JSON
{
"name": "Foo",
"price": 45.2
}
```
## 声明为参数
使用与声明路径和查询参数的相同方式声明请求体,即可将其添加到「路径操作」中:
```Python hl_lines="16"
{!../../../docs_src/body/tutorial001.py!}
```
...并且将它的类型声明为你创建的 `Item` 模型。
## 结果
仅仅使用了 Python 类型声明,**FastAPI** 将会:
* 将请求体作为 JSON 读取。
* 转换为相应的类型(在需要时)。
* 校验数据。
* 如果数据无效,将返回一条清晰易读的错误信息,指出不正确数据的确切位置和内容。
* 将接收的数据赋值到参数 `item` 中。
* 由于你已经在函数中将它声明为 `Item` 类型,你还将获得对于所有属性及其类型的一切编辑器支持(代码补全等)。
* 为你的模型生成 <a href="http://json-schema.org" class="external-link" target="_blank">JSON 模式</a> 定义,你还可以在其他任何对你的项目有意义的地方使用它们。
* 这些模式将成为生成的 OpenAPI 模式的一部分,并且被自动化文档 <abbr title="用户界面">UI</abbr> 所使用。
## 自动化文档
你所定义模型的 JSON 模式将成为生成的 OpenAPI 模式的一部分,并且在交互式 API 文档中展示:
<img src="https://fastapi.tiangolo.com/img/tutorial/body/image01.png">
而且还将在每一个需要它们的*路径操作*的 API 文档中使用:
<img src="https://fastapi.tiangolo.com/img/tutorial/body/image02.png">
## 编辑器支持
在你的编辑器中,你会在函数内部的任意地方得到类型提示和代码补全(如果你接收的是一个 `dict` 而不是 Pydantic 模型,则不会发生这种情况):
<img src="https://fastapi.tiangolo.com/img/tutorial/body/image03.png">
你还会获得对不正确的类型操作的错误检查:
<img src="https://fastapi.tiangolo.com/img/tutorial/body/image04.png">
这并非偶然,整个框架都是围绕该设计而构建。
并且在进行任何实现之前,已经在设计阶段经过了全面测试,以确保它可以在所有的编辑器中生效。
Pydantic 本身甚至也进行了一些更改以支持此功能。
上面的截图取自 <a href="https://code.visualstudio.com" class="external-link" target="_blank">Visual Studio Code</a>。
但是在 <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> 和绝大多数其他 Python 编辑器中你也会获得同样的编辑器支持:
<img src="https://fastapi.tiangolo.com/img/tutorial/body/image05.png">
## 使用模型
在函数内部,你可以直接访问模型对象的所有属性:
```Python hl_lines="19"
{!../../../docs_src/body/tutorial002.py!}
```
## 请求体 + 路径参数
你可以同时声明路径参数和请求体。
**FastAPI** 将识别出与路径参数匹配的函数参数应**从路径中获取**,而声明为 Pydantic 模型的函数参数应**从请求体中获取**。
```Python hl_lines="15 16"
{!../../../docs_src/body/tutorial003.py!}
```
## 请求体 + 路径参数 + 查询参数
你还可以同时声明**请求体**、**路径参数**和**查询参数**。
**FastAPI** 会识别它们中的每一个,并从正确的位置获取数据。
```Python hl_lines="16"
{!../../../docs_src/body/tutorial004.py!}
```
函数参数将依次按如下规则进行识别:
* 如果在**路径**中也声明了该参数,它将被用作路径参数。
* 如果参数属于**单一类型**(比如 `int`、`float`、`str`、`bool` 等)它将被解释为**查询**参数。
* 如果参数的类型被声明为一个 **Pydantic 模型**,它将被解释为**请求体**。
## 不使用 Pydantic
如果你不想使用 Pydantic 模型,你还可以使用 **Body** 参数。请参阅文档 [请求体 - 多个参数:请求体中的单一值](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank}。

View File

@@ -0,0 +1,335 @@
# 第一步
最简单的 FastAPI 文件可能像下面这样:
```Python
{!../../../docs_src/first_steps/tutorial001.py!}
```
将其复制到 `main.py` 文件中。
运行实时服务器:
<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)
<span style="color: green;">INFO</span>: Started reloader process [28720]
<span style="color: green;">INFO</span>: Started server process [28722]
<span style="color: green;">INFO</span>: Waiting for application startup.
<span style="color: green;">INFO</span>: Application startup complete.
```
</div>
!!! note
`uvicorn main:app` 命令含义如下:
* `main``main.py` 文件(一个 Python「模块」
* `app`:在 `main.py` 文件中通过 `app = FastAPI()` 创建的对象。
* `--reload`:让服务器在更新代码后重新启动。仅在开发时使用该选项。
在输出中,会有一行信息像下面这样:
```hl_lines="4"
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
该行显示了你的应用在本机所提供服务的 URL 地址。
### 查看
打开浏览器访问 <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>。
你将看到如下的 JSON 响应:
```JSON
{"message": "Hello World"}
```
### 交互式 API 文档
跳转到 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>。
你将会看到自动生成的交互式 API 文档(由 <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)
### 可选的 API 文档
前往 <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>。
你将会看到可选的自动生成文档 (由 <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)
### OpenAPI
**FastAPI** 使用定义 API 的 **OpenAPI** 标准将你的所有 API 转换成「模式」。
#### 「模式」
「模式」是对事物的一种定义或描述。它并非具体的实现代码,而只是抽象的描述。
#### API「模式」
在这种场景下OpenAPI 是一种规定如何定义 API 模式的规范。
定义的 OpenAPI 模式将包括你的 API 路径,以及它们可能使用的参数等等。
#### 数据「模式」
「模式」这个术语也可能指的是某些数据比如 JSON 的结构。
在这种情况下,它可以表示 JSON 的属性及其具有的数据类型,等等。
#### OpenAPI 和 JSON Schema
OpenAPI 为你的 API 定义 API 模式。该模式中包含了你的 API 发送和接收的数据的定义(或称为「模式」),这些定义通过 JSON 数据模式标准 **JSON Schema** 所生成。
#### 查看 `openapi.json`
如果你对原始的 OpenAPI 模式长什么样子感到好奇,其实它只是一个自动生成的包含了所有 API 描述的 JSON。
你可以直接在:<a href="http://127.0.0.1:8000/openapi.json" class="external-link" target="_blank">http://127.0.0.1:8000/openapi.json</a> 看到它。
它将显示以如下内容开头的 JSON
```JSON
{
"openapi": "3.0.2",
"info": {
"title": "FastAPI",
"version": "0.1.0"
},
"paths": {
"/items/": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
...
```
#### OpenAPI 的用途
驱动 FastAPI 内置的 2 个交互式文档系统的正是 OpenAPI 模式。
并且还有数十种替代方案,它们全部都基于 OpenAPI。你可以轻松地将这些替代方案中的任何一种添加到使用 **FastAPI** 构建的应用程序中。
你还可以使用它自动生成与你的 API 进行通信的客户端代码。例如 web 前端,移动端或物联网嵌入程序。
## 分步概括
### 步骤 1导入 `FastAPI`
```Python hl_lines="1"
{!../../../docs_src/first_steps/tutorial001.py!}
```
`FastAPI` 是一个为你的 API 提供了所有功能的 Python 类。
!!! note "技术细节"
`FastAPI` 是直接从 `Starlette` 继承的类。
你可以通过 `FastAPI` 使用所有的 Starlette 的功能。
### 步骤 2创建一个 `FastAPI`「实例」
```Python hl_lines="3"
{!../../../docs_src/first_steps/tutorial001.py!}
```
这里的变量 `app` 会是 `FastAPI` 类的一个「实例」。
这个实例将是创建你所有 API 的主要交互对象。
这个 `app` 同样在如下命令中被 `uvicorn` 所引用:
<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>
如果你像下面这样创建应用:
```Python hl_lines="3"
{!../../../docs_src/first_steps/tutorial002.py!}
```
将代码放入 `main.py` 文件中,然后你可以像下面这样运行 `uvicorn`
<div class="termy">
```console
$ uvicorn main:my_awesome_api --reload
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
### 步骤 3创建一个*路径操作*
#### 路径
这里的「路径」指的是 URL 中从第一个 `/` 起的后半部分。
所以,在一个这样的 URL 中:
```
https://example.com/items/foo
```
...路径会是:
```
/items/foo
```
!!! info
「路径」也通常被称为「端点」或「路由」。
开发 API 时,「路径」是用来分离「关注点」和「资源」的主要手段。
#### 操作
这里的「操作」指的是一种 HTTP「方法」。
下列之一:
* `POST`
* `GET`
* `PUT`
* `DELETE`
...以及更少见的几种:
* `OPTIONS`
* `HEAD`
* `PATCH`
* `TRACE`
在 HTTP 协议中,你可以使用以上的其中一种(或多种)「方法」与每个路径进行通信。
---
在开发 API 时,你通常使用特定的 HTTP 方法去执行特定的行为。
通常使用:
* `POST`:创建数据。
* `GET`:读取数据。
* `PUT`:更新数据。
* `DELETE`:删除数据。
因此,在 OpenAPI 中,每一个 HTTP 方法都被称为「操作」。
我们也打算称呼它们为「操作」。
#### 定义一个*路径操作装饰器*
```Python hl_lines="6"
{!../../../docs_src/first_steps/tutorial001.py!}
```
`@app.get("/")` 告诉 **FastAPI** 在它下方的函数负责处理如下访问请求:
* 请求路径为 `/`
* 使用 <abbr title="HTTP GET 方法"><code>get</code> 操作</abbr>
!!! info "`@decorator` Info"
`@something` 语法在 Python 中被称为「装饰器」。
像一顶漂亮的装饰帽一样,将它放在一个函数的上方(我猜测这个术语的命名就是这么来的)。
装饰器接收位于其下方的函数并且用它完成一些工作。
在我们的例子中,这个装饰器告诉 **FastAPI** 位于其下方的函数对应着**路径** `/` 加上 `get` **操作**。
它是一个「**路径操作装饰器**」。
你也可以使用其他的操作:
* `@app.post()`
* `@app.put()`
* `@app.delete()`
以及更少见的:
* `@app.options()`
* `@app.head()`
* `@app.patch()`
* `@app.trace()`
!!! tip
您可以随意使用任何一个操作HTTP方法
**FastAPI** 没有强制要求操作有任何特定的含义。
此处提供的信息仅作为指导,而不是要求。
比如,当使用 GraphQL 时通常你所有的动作都通过 `post` 一种方法执行。
### 步骤 4定义**路径操作函数**
这是我们的「**路径操作函数**」:
* **路径**:是 `/`。
* **操作**:是 `get`。
* **函数**:是位于「装饰器」下方的函数(位于 `@app.get("/")` 下方)。
```Python hl_lines="7"
{!../../../docs_src/first_steps/tutorial001.py!}
```
这是一个 Python 函数。
每当 **FastAPI** 接收一个使用 `GET` 方法访问 URL「`/`」的请求时这个函数会被调用。
在这个例子中,它是一个 `async` 函数。
---
你也可以将其定义为常规函数而不使用 `async def`:
```Python hl_lines="7"
{!../../../docs_src/first_steps/tutorial003.py!}
```
!!! note
如果你不知道两者的区别,请查阅 [Async: *"In a hurry?"*](https://fastapi.tiangolo.com/async/#in-a-hurry){.internal-link target=_blank}。
### 步骤 5返回内容
```Python hl_lines="8"
{!../../../docs_src/first_steps/tutorial001.py!}
```
你可以返回一个 `dict`、`list`,像 `str`、`int` 一样的单个值,等等。
你还可以返回 Pydantic 模型(稍后你将了解更多)。
还有许多其他将会自动转换为 JSON 的对象和模型(包括 ORM 对象等)。尝试下使用你最喜欢的一种,它很有可能已经被支持。
## 总结
* 导入 `FastAPI`。
* 创建一个 `app` 实例。
* 编写一个**路径操作装饰器**(如 `@app.get("/")`)。
* 编写一个**路径操作函数**(如上面的 `def root(): ...`)。
* 运行开发服务器(如 `uvicorn main:app --reload`)。

View File

@@ -0,0 +1,122 @@
# 路径参数和数值校验
与使用 `Query` 为查询参数声明更多的校验和元数据的方式相同,你也可以使用 `Path` 为路径参数声明相同类型的校验和元数据。
## 导入 Path
首先,从 `fastapi` 导入 `Path`
```Python hl_lines="1"
{!../../../docs_src/path_params_numeric_validations/tutorial001.py!}
```
## 声明元数据
你可以声明与 `Query` 相同的所有参数。
例如,要声明路径参数 `item_id`的 `title` 元数据值,你可以输入:
```Python hl_lines="8"
{!../../../docs_src/path_params_numeric_validations/tutorial001.py!}
```
!!! note
路径参数总是必需的,因为它必须是路径的一部分。
所以,你应该在声明时使用 `...` 将其标记为必需参数。
然而,即使你使用 `None` 声明路径参数或设置一个其他默认值也不会有任何影响,它依然会是必需参数。
## 按需对参数排序
假设你想要声明一个必需的 `str` 类型查询参数 `q`。
而且你不需要为该参数声明任何其他内容,所以实际上你并不需要使用 `Query`。
但是你仍然需要使用 `Path` 来声明路径参数 `item_id`。
如果你将带有「默认值」的参数放在没有「默认值」的参数之前Python 将会报错。
但是你可以对其重新排序,并将不带默认值的值(查询参数 `q`)放到最前面。
对 **FastAPI** 来说这无关紧要。它将通过参数的名称、类型和默认值声明(`Query`、`Path` 等)来检测参数,而不在乎参数的顺序。
因此,你可以将函数声明为:
```Python hl_lines="8"
{!../../../docs_src/path_params_numeric_validations/tutorial002.py!}
```
## 按需对参数排序的技巧
如果你想不使用 `Query` 声明没有默认值的查询参数 `q`,同时使用 `Path` 声明路径参数 `item_id`并使它们的顺序与上面不同Python 对此有一些特殊的语法。
传递 `*` 作为函数的第一个参数。
Python 不会对该 `*` 做任何事情,但是它将知道之后的所有参数都应作为关键字参数(键值对),也被称为 <abbr title="来自K-ey W-ord Arg-uments"><code>kwargs</code></abbr>,来调用。即使它们没有默认值。
```Python hl_lines="8"
{!../../../docs_src/path_params_numeric_validations/tutorial003.py!}
```
## 数值校验:大于等于
使用 `Query` 和 `Path`(以及你将在后面看到的其他类)可以声明字符串约束,但也可以声明数值约束。
像下面这样,添加 `ge=1` 后,`item_id` 将必须是一个大于(`g`reater than或等于`e`qual`1` 的整数。
```Python hl_lines="8"
{!../../../docs_src/path_params_numeric_validations/tutorial004.py!}
```
## 数值校验:大于和小于等于
同样的规则适用于:
* `gt`:大于(`g`reater `t`han
* `le`:小于等于(`l`ess than or `e`qual
```Python hl_lines="9"
{!../../../docs_src/path_params_numeric_validations/tutorial005.py!}
```
## 数值校验:浮点数、大于和小于
数值校验同样适用于 `float` 值。
能够声明 <abbr title="大于"><code>gt</code></abbr> 而不仅仅是 <abbr title="大于等于"><code>ge</code></abbr> 在这个前提下变得重要起来。例如,你可以要求一个值必须大于 `0`,即使它小于 `1`。
因此,`0.5` 将是有效值。但是 `0.0`或 `0` 不是。
对于 <abbr title="less than"><code>lt</code></abbr> 也是一样的。
```Python hl_lines="11"
{!../../../docs_src/path_params_numeric_validations/tutorial006.py!}
```
## 总结
你能够以与 [查询参数和字符串校验](query-params-str-validations.md){.internal-link target=_blank} 相同的方式使用 `Query`、`Path`(以及其他你还没见过的类)声明元数据和字符串校验。
而且你还可以声明数值校验:
* `gt`:大于(`g`reater `t`han
* `ge`:大于等于(`g`reater than or `e`qual
* `lt`:小于(`l`ess `t`han
* `le`:小于等于(`l`ess than or `e`qual
!!! info
`Query`、`Path` 以及你后面会看到的其他类继承自一个共同的 `Param` 类(不需要直接使用它)。
而且它们都共享相同的所有你已看到并用于添加额外校验和元数据的参数。
!!! note "技术细节"
当你从 `fastapi` 导入 `Query`、`Path` 和其他同类对象时,它们实际上是函数。
当被调用时,它们返回同名类的实例。
如此,你导入 `Query` 这个函数。当你调用它时,它将返回一个同样命名为 `Query` 的类的实例。
因为使用了这些函数(而不是直接使用类),所以你的编辑器不会标记有关其类型的错误。
这样,你可以使用常规的编辑器和编码工具,而不必添加自定义配置来忽略这些错误。

View File

@@ -0,0 +1,234 @@
# 路径参数
你可以使用与 Python 格式化字符串相同的语法来声明路径"参数"或"变量"
```Python hl_lines="6 7"
{!../../../docs_src/path_params/tutorial001.py!}
```
路径参数 `item_id` 的值将作为参数 `item_id` 传递给你的函数。
所以,如果你运行示例并访问 <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a>,将会看到如下响应:
```JSON
{"item_id":"foo"}
```
## 有类型的路径参数
你可以使用标准的 Python 类型标注为函数中的路径参数声明类型。
```Python hl_lines="7"
{!../../../docs_src/path_params/tutorial002.py!}
```
在这个例子中,`item_id` 被声明为 `int` 类型。
!!! check
这将为你的函数提供编辑器支持,包括错误检查、代码补全等等。
## 数据<abbr title="也被称为:序列化、解析">转换</abbr>
如果你运行示例并打开浏览器访问 <a href="http://127.0.0.1:8000/items/3" class="external-link" target="_blank">http://127.0.0.1:8000/items/3</a>,将得到如下响应:
```JSON
{"item_id":3}
```
!!! check
注意函数接收(并返回)的值为 3是一个 Python `int` 值,而不是字符串 `"3"`。
所以,**FastAPI** 通过上面的类型声明提供了对请求的自动<abbr title="将来自 HTTP 请求中的字符串转换为 Python 数据类型">"解析"</abbr>。
## 数据校验
但如果你通过浏览器访问 <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a>,你会看到一个清晰可读的 HTTP 错误:
```JSON
{
"detail": [
{
"loc": [
"path",
"item_id"
],
"msg": "value is not a valid integer",
"type": "type_error.integer"
}
]
}
```
因为路径参数 `item_id` 传入的值为 `"foo"`,它不是一个 `int`。
如果你提供的是 `float` 而非整数也会出现同样的错误,比如: <a href="http://127.0.0.1:8000/items/4.2" class="external-link" target="_blank">http://127.0.0.1:8000/items/4.2</a>
!!! check
所以,通过同样的 Python 类型声明,**FastAPI** 提供了数据校验功能。
注意上面的错误同样清楚地指出了校验未通过的具体原因。
在开发和调试与你的 API 进行交互的代码时,这非常有用。
## 文档
当你打开浏览器访问 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>,你将看到自动生成的交互式 API 文档:
<img src="https://fastapi.tiangolo.com/img/tutorial/path-params/image01.png">
!!! check
再一次,还是通过相同的 Python 类型声明,**FastAPI** 为你提供了自动生成的交互式文档(集成 Swagger UI
注意这里的路径参数被声明为一个整数。
## 基于标准的好处:可选文档
由于生成的 API 模式来自于 <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md" class="external-link" target="_blank">OpenAPI</a> 标准,所以有很多工具与其兼容。
正因如此,**FastAPI** 内置了一个可选的 API 文档(使用 Redoc
<img src="https://fastapi.tiangolo.com/img/tutorial/path-params/image02.png">
同样的,还有很多其他兼容的工具,包括适用于多种语言的代码生成工具。
## Pydantic
所有的数据校验都由 <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> 在幕后完成,所以你可以从它所有的优点中受益。并且你知道它在这方面非常胜任。
你可以使用同样的类型声明来声明 `str`、`float`、`bool` 以及许多其他的复合数据类型。
本教程的下一章节将探讨其中的一些内容。
## 顺序很重要
在创建*路径操作*时,你会发现有些情况下路径是固定的。
比如 `/users/me`,我们假设它用来获取关于当前用户的数据.
然后,你还可以使用路径 `/users/{user_id}` 来通过用户 ID 获取关于特定用户的数据。
由于*路径操作*是按顺序依次运行的,你需要确保路径 `/users/me` 声明在路径 `/users/{user_id}`之前:
```Python hl_lines="6 11"
{!../../../docs_src/path_params/tutorial003.py!}
```
否则,`/users/{user_id}` 的路径还将与 `/users/me` 相匹配,"认为"自己正在接收一个值为 `"me"` 的 `user_id` 参数。
## 预设值
如果你有一个接收路径参数的路径操作,但你希望预先设定可能的有效参数值,则可以使用标准的 Python <abbr title="Enumeration">`Enum`</abbr> 类型。
### 创建一个 `Enum` 类
导入 `Enum` 并创建一个继承自 `str` 和 `Enum` 的子类。
通过从 `str` 继承API 文档将能够知道这些值必须为 `string` 类型并且能够正确地展示出来。
然后创建具有固定值的类属性,这些固定值将是可用的有效值:
```Python hl_lines="1 6 7 8 9"
{!../../../docs_src/path_params/tutorial005.py!}
```
!!! info
<a href="https://docs.python.org/3/library/enum.html" class="external-link" target="_blank">枚举(或 enums</a>从 3.4 版本起在 Python 中可用。
!!! tip
如果你想知道,"AlexNet"、"ResNet" 和 "LeNet" 只是机器学习中的<abbr title="技术上来说是深度学习模型架构">模型</abbr>名称。
### 声明*路径参数*
然后使用你定义的枚举类(`ModelName`)创建一个带有类型标注的*路径参数*
```Python hl_lines="16"
{!../../../docs_src/path_params/tutorial005.py!}
```
### 查看文档
因为已经指定了*路径参数*的可用值,所以交互式文档可以恰当地展示它们:
<img src="https://fastapi.tiangolo.com/img/tutorial/path-params/image03.png">
### 使用 Python *枚举类型*
*路径参数*的值将是一个*枚举成员*。
#### 比较*枚举成员*
你可以将它与你创建的枚举类 `ModelName` 中的*枚举成员*进行比较:
```Python hl_lines="17"
{!../../../docs_src/path_params/tutorial005.py!}
```
#### 获取*枚举值*
你可以使用 `model_name.value` 或通常来说 `your_enum_member.value` 来获取实际的值(在这个例子中为 `str`
```Python hl_lines="19"
{!../../../docs_src/path_params/tutorial005.py!}
```
!!! tip
你也可以通过 `ModelName.lenet.value` 来获取值 `"lenet"`。
#### 返回*枚举成员*
你可以从*路径操作*中返回*枚举成员*,即使嵌套在 JSON 结构中(例如一个 `dict` 中)。
在返回给客户端之前,它们将被转换为对应的值:
```Python hl_lines="18 20 21"
{!../../../docs_src/path_params/tutorial005.py!}
```
## 包含路径的路径参数
假设你有一个*路径操作*,它的路径为 `/files/{file_path}`。
但是你需要 `file_path` 自身也包含*路径*,比如 `home/johndoe/myfile.txt`。
因此该文件的URL将类似于这样`/files/home/johndoe/myfile.txt`。
### OpenAPI 支持
OpenAPI 不支持任何方式去声明*路径参数*以在其内部包含*路径*,因为这可能会导致难以测试和定义的情况出现。
不过,你仍然可以通过 Starlette 的一个内部工具在 **FastAPI** 中实现它。
而且文档依旧可以使用,但是不会添加任何该参数应包含路径的说明。
### 路径转换器
你可以使用直接来自 Starlette 的选项来声明一个包含*路径*的*路径参数*
```
/files/{file_path:path}
```
在这种情况下,参数的名称为 `file_path`,结尾部分的 `:path` 说明该参数应匹配任意的*路径*。
因此,你可以这样使用它:
```Python hl_lines="6"
{!../../../docs_src/path_params/tutorial004.py!}
```
!!! tip
你可能会需要参数包含 `/home/johndoe/myfile.txt`,以斜杠(`/`)开头。
在这种情况下URL 将会是 `/files//home/johndoe/myfile.txt`,在`files` 和 `home` 之间有一个双斜杠(`//`)。
## 总结
使用 **FastAPI**,通过简短、直观和标准的 Python 类型声明,你将获得:
* 编辑器支持:错误检查,代码补全等
* 数据 "<abbr title="将来自 HTTP 请求中的字符串转换为 Python 数据类型">解析</abbr>"
* 数据校验
* API 标注和自动生成的文档
而且你只需要声明一次即可。
这可能是 **FastAPI** 与其他框架相比主要的明显优势(除了原始性能以外)。

View File

@@ -0,0 +1,281 @@
# 查询参数和字符串校验
**FastAPI** 允许你为参数声明额外的信息和校验。
让我们以下面的应用程序为例:
```Python hl_lines="7"
{!../../../docs_src/query_params_str_validations/tutorial001.py!}
```
查询参数 `q` 的类型为 `str`,默认值为 `None`,因此它是可选的。
## 额外的校验
我们打算添加约束条件:即使 `q` 是可选的,但只要提供了该参数,则该参数值**不能超过50个字符的长度**。
### 导入 `Query`
为此,首先从 `fastapi` 导入 `Query`
```Python hl_lines="1"
{!../../../docs_src/query_params_str_validations/tutorial002.py!}
```
## 使用 `Query` 作为默认值
现在,将 `Query` 用作查询参数的默认值,并将它的 `max_length` 参数设置为 50
```Python hl_lines="7"
{!../../../docs_src/query_params_str_validations/tutorial002.py!}
```
由于我们必须用 `Query(None)` 替换默认值 `None``Query` 的第一个参数同样也是用于定义默认值。
所以:
```Python
q: str = Query(None)
```
...使得参数可选,等同于:
```Python
q: str = None
```
但是 `Query` 显式地将其声明为查询参数。
然后,我们可以将更多的参数传递给 `Query`。在本例中,适用于字符串的 `max_length` 参数:
```Python
q: str = Query(None, max_length=50)
```
将会校验数据,在数据无效时展示清晰的错误信息,并在 OpenAPI 模式的*路径操作*中记录该参​​数。
## 添加更多校验
你还可以添加 `min_length` 参数:
```Python hl_lines="7"
{!../../../docs_src/query_params_str_validations/tutorial003.py!}
```
## 添加正则表达式
你可以定义一个参数值必须匹配的<abbr title="正则表达式或正则是定义字符串搜索模式的字符序列。">正则表达式</abbr>
```Python hl_lines="8"
{!../../../docs_src/query_params_str_validations/tutorial004.py!}
```
这个指定的正则表达式通过以下规则检查接收到的参数值:
* `^`:以该符号之后的字符开头,符号之前没有字符。
* `fixedquery`: 值精确地等于 `fixedquery`。
* `$`: 到此结束,在 `fixedquery` 之后没有更多字符。
如果你对所有的这些**「正则表达式」**概念感到迷茫,请不要担心。对于许多人来说这都是一个困难的主题。你仍然可以在无需正则表达式的情况下做很多事情。
但是,一旦你需要用到并去学习它们时,请了解你已经可以在 **FastAPI** 中直接使用它们。
## 默认值
你可以向 `Query` 的第一个参数传入 `None` 用作查询参数的默认值,以同样的方式你也可以传递其他默认值。
假设你想要声明查询参数 `q`,使其 `min_length` 为 `3`,并且默认值为 `fixedquery`
```Python hl_lines="7"
{!../../../docs_src/query_params_str_validations/tutorial005.py!}
```
!!! note
具有默认值还会使该参数成为可选参数。
## 声明为必需参数
当我们不需要声明额外的校验或元数据时,只需不声明默认值就可以使 `q` 参数成为必需参数,例如:
```Python
q: str
```
代替:
```Python
q: str = None
```
但是现在我们正在用 `Query` 声明它,例如:
```Python
q: str = Query(None, min_length=3)
```
因此,当你在使用 `Query` 且需要声明一个值是必需的时,可以将 `...` 用作第一个参数值:
```Python hl_lines="7"
{!../../../docs_src/query_params_str_validations/tutorial006.py!}
```
!!! info
如果你之前没见过 `...` 这种用法:它是一个特殊的单独值,它是 <a href="https://docs.python.org/3/library/constants.html#Ellipsis" class="external-link" target="_blank">Python 的一部分并且被称为「省略号」</a>。
这将使 **FastAPI** 知道此查询参数是必需的。
## 查询参数列表 / 多个值
当你使用 `Query` 显式地定义查询参数时,你还可以声明它去接收一组值,或换句话来说,接收多个值。
例如,要声明一个可在 URL 中出现多次的查询参数 `q`,你可以这样写:
```Python hl_lines="9"
{!../../../docs_src/query_params_str_validations/tutorial011.py!}
```
然后,输入如下网址:
```
http://localhost:8000/items/?q=foo&q=bar
```
你会在*路径操作函数*的*函数参数* `q` 中以一个 Python `list` 的形式接收到*查询参数* `q` 的多个值(`foo` 和 `bar`)。
因此,该 URL 的响应将会是:
```JSON
{
"q": [
"foo",
"bar"
]
}
```
!!! tip
要声明类型为 `list` 的查询参数,如上例所示,你需要显式地使用 `Query`,否则该参数将被解释为请求体。
交互式 API 文档将会相应地进行更新,以允许使用多个值:
<img src="https://fastapi.tiangolo.com/img/tutorial/query-params-str-validations/image02.png">
### 具有默认值的查询参数列表 / 多个值
你还可以定义在没有任何给定值时的默认 `list` 值:
```Python hl_lines="9"
{!../../../docs_src/query_params_str_validations/tutorial012.py!}
```
如果你访问:
```
http://localhost:8000/items/
```
`q` 的默认值将为:`["foo", "bar"]`,你的响应会是:
```JSON
{
"q": [
"foo",
"bar"
]
}
```
#### 使用 `list`
你也可以直接使用 `list` 代替 `List [str]`
```Python hl_lines="7"
{!../../../docs_src/query_params_str_validations/tutorial013.py!}
```
!!! note
请记住,在这种情况下 FastAPI 将不会检查列表的内容。
例如,`List[int]` 将检查(并记录到文档)列表的内容必须是整数。但是单独的 `list` 不会。
## 声明更多元数据
你可以添加更多有关该参数的信息。
这些信息将包含在生成的 OpenAPI 模式中,并由文档用户界面和外部工具所使用。
!!! note
请记住,不同的工具对 OpenAPI 的支持程度可能不同。
其中一些可能不会展示所有已声明的额外信息,尽管在大多数情况下,缺少的这部分功能已经计划进行开发。
你可以添加 `title`
```Python hl_lines="7"
{!../../../docs_src/query_params_str_validations/tutorial007.py!}
```
以及 `description`
```Python hl_lines="11"
{!../../../docs_src/query_params_str_validations/tutorial008.py!}
```
## 别名参数
假设你想要查询参数为 `item-query`。
像下面这样:
```
http://127.0.0.1:8000/items/?item-query=foobaritems
```
但是 `item-query` 不是一个有效的 Python 变量名称。
最接近的有效名称是 `item_query`。
但是你仍然要求它在 URL 中必须是 `item-query`...
这时你可以用 `alias` 参数声明一个别名,该别名将用于在 URL 中查找查询参数值:
```Python hl_lines="7"
{!../../../docs_src/query_params_str_validations/tutorial009.py!}
```
## 弃用参数
现在假设你不再喜欢此参数。
你不得不将其保留一段时间,因为有些客户端正在使用它,但你希望文档清楚地将其展示为<abbr title ="已过时,建议不要使用它">已弃用</abbr>。
那么将参数 `deprecated=True` 传入 `Query`
```Python hl_lines="16"
{!../../../docs_src/query_params_str_validations/tutorial010.py!}
```
文档将会像下面这样展示它:
<img src="https://fastapi.tiangolo.com/img/tutorial/query-params-str-validations/image01.png">
## 总结
你可以为查询参数声明额外的校验和元数据。
通用的校验和元数据:
* `alias`
* `title`
* `description`
* `deprecated`
特定于字符串的校验:
* `min_length`
* `max_length`
* `regex`
在这些示例中,你了解了如何声明对 `str` 值的校验。
请参阅下一章节,以了解如何声明对其他类型例如数值的校验。

View File

@@ -0,0 +1,226 @@
# 查询参数
声明不属于路径参数的其他函数参数时,它们将被自动解释为"查询字符串"参数
```Python hl_lines="9"
{!../../../docs_src/query_params/tutorial001.py!}
```
查询字符串是键值对的集合,这些键值对位于 URL 的 `` 之后,并以 `&` 符号分隔。
例如,在以下 url 中:
```
http://127.0.0.1:8000/items/?skip=0&limit=10
```
...查询参数为:
* `skip`:对应的值为 `0`
* `limit`:对应的值为 `10`
由于它们是 URL 的一部分,因此它们的"原始值"是字符串。
但是,当你为它们声明了 Python 类型(在上面的示例中为 `int`)时,它们将转换为该类型并针对该类型进行校验。
应用于路径参数的所有相同过程也适用于查询参数:
* (很明显的)编辑器支持
* 数据<abbr title="将来自 HTTP 请求的字符串转换为 Python 数据类型">"解析"</abbr>
* 数据校验
* 自动生成文档
## 默认值
由于查询参数不是路径的固定部分,因此它们可以是可选的,并且可以有默认值。
在上面的示例中,它们具有 `skip=0` 和 `limit=10` 的默认值。
因此,访问 URL
```
http://127.0.0.1:8000/items/
```
将与访问以下地址相同:
```
http://127.0.0.1:8000/items/?skip=0&limit=10
```
但是,如果你访问的是:
```
http://127.0.0.1:8000/items/?skip=20
```
函数中的参数值将会是:
* `skip=20`:在 URL 中设定的值
* `limit=10`:使用默认值
## 可选参数
通过同样的方式,你可以将它们的默认值设置为 `None` 来声明可选查询参数:
```Python hl_lines="7"
{!../../../docs_src/query_params/tutorial002.py!}
```
在这个例子中,函数参数 `q` 将是可选的,并且默认值为 `None`。
!!! check
还要注意的是,**FastAPI** 足够聪明,能够分辨出参数 `item_id` 是路径参数而 `q` 不是,因此 `q` 是一个查询参数。
## 查询参数类型转换
你还可以声明 `bool` 类型,它们将被自动转换:
```Python hl_lines="7"
{!../../../docs_src/query_params/tutorial003.py!}
```
这个例子中,如果你访问:
```
http://127.0.0.1:8000/items/foo?short=1
```
```
http://127.0.0.1:8000/items/foo?short=True
```
```
http://127.0.0.1:8000/items/foo?short=true
```
```
http://127.0.0.1:8000/items/foo?short=on
```
```
http://127.0.0.1:8000/items/foo?short=yes
```
或任何其他的变体形式(大写,首字母大写等等),你的函数接收的 `short` 参数都会是布尔值 `True`。对于值为 `False` 的情况也是一样的。
## 多个路径和查询参数
你可以同时声明多个路径参数和查询参数,**FastAPI** 能够识别它们。
而且你不需要以任何特定的顺序来声明。
它们将通过名称被检测到:
```Python hl_lines="6 8"
{!../../../docs_src/query_params/tutorial004.py!}
```
## 必需查询参数
当你为非路径参数声明了默认值时(目前而言,我们所知道的仅有查询参数),则该参数不是必需的。
如果你不想添加一个特定的值,而只是想使该参数成为可选的,则将默认值设置为 `None`。
但当你想让一个查询参数成为必需的,不声明任何默认值就可以:
```Python hl_lines="6 7"
{!../../../docs_src/query_params/tutorial005.py!}
```
这里的查询参数 `needy` 是类型为 `str` 的必需查询参数。
如果你在浏览器中打开一个像下面的 URL
```
http://127.0.0.1:8000/items/foo-item
```
...因为没有添加必需的参数 `needy`,你将看到类似以下的错误:
```JSON
{
"detail": [
{
"loc": [
"query",
"needy"
],
"msg": "field required",
"type": "value_error.missing"
}
]
}
```
由于 `needy` 是必需参数,因此你需要在 URL 中设置它的值:
```
http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
```
...这样就正常了:
```JSON
{
"item_id": "foo-item",
"needy": "sooooneedy"
}
```
当然,你也可以定义一些参数为必需的,一些具有默认值,而某些则完全是可选的:
```Python hl_lines="7"
{!../../../docs_src/query_params/tutorial006.py!}
```
在这个例子中有3个查询参数
* `needy`,一个必需的 `str` 类型参数。
* `skip`,一个默认值为 `0` 的 `int` 类型参数。
* `limit`,一个可选的 `int` 类型参数。
!!! tip
你还可以像在 [路径参数](path-params.md#predefined-values){.internal-link target=_blank} 中那样使用 `Enum`。
## Optional 类型声明
!!! warning
这可能是一个比较高级的使用场景。
您也可以跳过它。
如果你正在使用 `mypy`,它可能会对如下的类型声明进行警告:
```Python
limit: int = None
```
提示类似以下错误:
```
Incompatible types in assignment (expression has type "None", variable has type "int")
```
在这种情况下,你可以使用 `Optional` 来告诉 `mypy` 该值可以为 `None`,例如:
```Python
from typing import Optional
limit: Optional[int] = None
```
在一个*路径操作*中,看起来会是:
```Python hl_lines="9"
{!../../../docs_src/query_params/tutorial007.py!}
```

View File

@@ -22,12 +22,25 @@ nav:
- Languages:
- en: /
- es: /es/
- it: /it/
- pt: /pt/
- ru: /ru/
- zh: /zh/
- features.md
- python-types.md
- 教程 - 用户指南:
- tutorial/index.md
- tutorial/first-steps.md
- tutorial/path-params.md
- tutorial/query-params.md
- tutorial/body.md
- tutorial/query-params-str-validations.md
- tutorial/path-params-numeric-validations.md
- tutorial/body-multiple-params.md
- tutorial/body-fields.md
- deployment.md
- contributing.md
- help-fastapi.md
markdown_extensions:
- toc:
permalink: true

View File

@@ -1,3 +1,5 @@
from typing import Optional
from fastapi import FastAPI
from fastapi.responses import FileResponse
from pydantic import BaseModel
@@ -21,7 +23,7 @@ app = FastAPI()
}
},
)
async def read_item(item_id: str, img: bool = None):
async def read_item(item_id: str, img: Optional[bool] = None):
if img:
return FileResponse("image.png", media_type="image/png")
else:

View File

@@ -1,3 +1,5 @@
from typing import Optional
from fastapi import FastAPI
from fastapi.responses import FileResponse
from pydantic import BaseModel
@@ -23,7 +25,7 @@ app = FastAPI()
response_model=Item,
responses={**responses, 200: {"content": {"image/png": {}}}},
)
async def read_item(item_id: str, img: bool = None):
async def read_item(item_id: str, img: Optional[bool] = None):
if img:
return FileResponse("image.png", media_type="image/png")
else:

View File

@@ -1,3 +1,5 @@
from typing import Optional
from fastapi import Body, FastAPI, status
from fastapi.responses import JSONResponse
@@ -7,7 +9,9 @@ items = {"foo": {"name": "Fighters", "size": 6}, "bar": {"name": "Tenders", "siz
@app.put("/items/{item_id}")
async def upsert_item(item_id: str, name: str = Body(None), size: int = Body(None)):
async def upsert_item(
item_id: str, name: Optional[str] = Body(None), size: Optional[int] = Body(None)
):
if item_id in items:
item = items[item_id]
item["name"] = name

View File

@@ -1,3 +1,5 @@
from typing import Optional
from fastapi import FastAPI, Header, HTTPException
from pydantic import BaseModel
@@ -14,7 +16,7 @@ app = FastAPI()
class Item(BaseModel):
id: str
title: str
description: str = None
description: Optional[str] = None
@app.get("/items/{item_id}", response_model=Item)

View File

@@ -51,7 +51,7 @@ def test_create_item_bad_token():
assert response.json() == {"detail": "Invalid X-Token header"}
def test_create_existing_token():
def test_create_existing_item():
response = client.post(
"/items/",
headers={"X-Token": "coneofsilence"},

View File

@@ -1,3 +1,5 @@
from typing import Optional
from fastapi import BackgroundTasks, Depends, FastAPI
app = FastAPI()
@@ -8,7 +10,7 @@ def write_log(message: str):
log.write(message)
def get_query(background_tasks: BackgroundTasks, q: str = None):
def get_query(background_tasks: BackgroundTasks, q: Optional[str] = None):
if q:
message = f"found query: {q}\n"
background_tasks.add_task(write_log, message)

View File

@@ -0,0 +1,8 @@
from fastapi import FastAPI, Request
app = FastAPI()
@app.get("/app")
def read_main(request: Request):
return {"message": "Hello World", "root_path": request.scope.get("root_path")}

View File

@@ -0,0 +1,8 @@
from fastapi import FastAPI, Request
app = FastAPI(root_path="/api/v1")
@app.get("/app")
def read_main(request: Request):
return {"message": "Hello World", "root_path": request.scope.get("root_path")}

View File

@@ -1,12 +1,14 @@
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str = None
description: Optional[str] = None
price: float
tax: float = None
tax: Optional[float] = None
app = FastAPI()

View File

@@ -1,12 +1,14 @@
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str = None
description: Optional[str] = None
price: float
tax: float = None
tax: Optional[float] = None
app = FastAPI()

View File

@@ -1,12 +1,14 @@
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str = None
description: Optional[str] = None
price: float
tax: float = None
tax: Optional[float] = None
app = FastAPI()

View File

@@ -1,19 +1,21 @@
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str = None
description: Optional[str] = None
price: float
tax: float = None
tax: Optional[float] = None
app = FastAPI()
@app.put("/items/{item_id}")
async def create_item(item_id: int, item: Item, q: str = None):
async def create_item(item_id: int, item: Item, q: Optional[str] = None):
result = {"item_id": item_id, **item.dict()}
if q:
result.update({"q": q})

View File

@@ -1,3 +1,5 @@
from typing import Optional
from fastapi import Body, FastAPI
from pydantic import BaseModel, Field
@@ -6,12 +8,14 @@ app = FastAPI()
class Item(BaseModel):
name: str
description: str = Field(None, title="The description of the item", max_length=300)
description: Optional[str] = Field(
None, title="The description of the item", max_length=300
)
price: float = Field(..., gt=0, description="The price must be greater than zero")
tax: float = None
tax: Optional[float] = None
@app.put("/items/{item_id}")
async def update_item(*, item_id: int, item: Item = Body(..., embed=True)):
async def update_item(item_id: int, item: Item = Body(..., embed=True)):
results = {"item_id": item_id, "item": item}
return results

View File

@@ -1,3 +1,5 @@
from typing import Optional
from fastapi import FastAPI, Path
from pydantic import BaseModel
@@ -6,17 +8,17 @@ app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
description: Optional[str] = None
price: float
tax: float = None
tax: Optional[float] = None
@app.put("/items/{item_id}")
async def update_item(
*,
item_id: int = Path(..., title="The ID of the item to get", ge=0, le=1000),
q: str = None,
item: Item = None,
q: Optional[str] = None,
item: Optional[Item] = None,
):
results = {"item_id": item_id}
if q:

View File

@@ -1,3 +1,5 @@
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
@@ -6,17 +8,17 @@ app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
description: Optional[str] = None
price: float
tax: float = None
tax: Optional[float] = None
class User(BaseModel):
username: str
full_name: str = None
full_name: Optional[str] = None
@app.put("/items/{item_id}")
async def update_item(*, item_id: int, item: Item, user: User):
async def update_item(item_id: int, item: Item, user: User):
results = {"item_id": item_id, "item": item, "user": user}
return results

View File

@@ -1,3 +1,5 @@
from typing import Optional
from fastapi import Body, FastAPI
from pydantic import BaseModel
@@ -6,19 +8,19 @@ app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
description: Optional[str] = None
price: float
tax: float = None
tax: Optional[float] = None
class User(BaseModel):
username: str
full_name: str = None
full_name: Optional[str] = None
@app.put("/items/{item_id}")
async def update_item(
*, item_id: int, item: Item, user: User, importance: int = Body(...)
item_id: int, item: Item, user: User, importance: int = Body(...)
):
results = {"item_id": item_id, "item": item, "user": user, "importance": importance}
return results

View File

@@ -1,3 +1,5 @@
from typing import Optional
from fastapi import Body, FastAPI
from pydantic import BaseModel
@@ -6,14 +8,14 @@ app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
description: Optional[str] = None
price: float
tax: float = None
tax: Optional[float] = None
class User(BaseModel):
username: str
full_name: str = None
full_name: Optional[str] = None
@app.put("/items/{item_id}")
@@ -23,7 +25,7 @@ async def update_item(
item: Item,
user: User,
importance: int = Body(..., gt=0),
q: str = None
q: Optional[str] = None
):
results = {"item_id": item_id, "item": item, "user": user, "importance": importance}
if q:

View File

@@ -1,3 +1,5 @@
from typing import Optional
from fastapi import Body, FastAPI
from pydantic import BaseModel
@@ -6,12 +8,12 @@ app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
description: Optional[str] = None
price: float
tax: float = None
tax: Optional[float] = None
@app.put("/items/{item_id}")
async def update_item(*, item_id: int, item: Item = Body(..., embed=True)):
async def update_item(item_id: int, item: Item = Body(..., embed=True)):
results = {"item_id": item_id, "item": item}
return results

View File

@@ -1,3 +1,5 @@
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
@@ -6,13 +8,13 @@ app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
description: Optional[str] = None
price: float
tax: float = None
tax: Optional[float] = None
tags: list = []
@app.put("/items/{item_id}")
async def update_item(*, item_id: int, item: Item):
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results

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