Browse Source

Merge branch 'master' into dev-getquery

pull/4573/head
jujumilk3 2 years ago
parent
commit
c678efe213
  1. 4
      .github/actions/people/app/main.py
  2. 7
      .github/workflows/build-docs.yml
  3. 2
      .github/workflows/preview-docs.yml
  4. 18
      .github/workflows/publish.yml
  5. 8
      .github/workflows/test.yml
  6. 8
      .pre-commit-config.yaml
  7. 8
      README.md
  8. 2
      SECURITY.md
  9. 466
      docs/az/docs/index.md
  10. 2
      docs/de/docs/index.md
  11. 8
      docs/en/data/external_links.yml
  12. 232
      docs/en/data/github_sponsors.yml
  13. 222
      docs/en/data/people.yml
  14. 2
      docs/en/docs/advanced/dataclasses.md
  15. 44
      docs/en/docs/contributing.md
  16. 8
      docs/en/docs/index.md
  17. 113
      docs/en/docs/release-notes.md
  18. 2
      docs/en/docs/tutorial/query-params-str-validations.md
  19. 2
      docs/en/docs/tutorial/response-model.md
  20. 2
      docs/es/docs/index.md
  21. 2
      docs/fr/docs/index.md
  22. 2
      docs/id/docs/index.md
  23. 2
      docs/it/docs/index.md
  24. 45
      docs/ja/docs/contributing.md
  25. 2
      docs/ja/docs/index.md
  26. 2
      docs/ko/docs/index.md
  27. 2
      docs/nl/docs/index.md
  28. 2
      docs/pl/docs/index.md
  29. 44
      docs/pt/docs/contributing.md
  30. 2
      docs/pt/docs/index.md
  31. 1
      docs/pt/mkdocs.yml
  32. 203
      docs/ru/docs/features.md
  33. 2
      docs/ru/docs/index.md
  34. 1
      docs/ru/mkdocs.yml
  35. 2
      docs/sq/docs/index.md
  36. 2
      docs/sv/docs/index.md
  37. 2
      docs/tr/docs/index.md
  38. 2
      docs/uk/docs/index.md
  39. 44
      docs/zh/docs/contributing.md
  40. 42
      docs/zh/docs/tutorial/encoder.md
  41. 63
      docs/zh/docs/tutorial/request-files.md
  42. 1
      docs/zh/mkdocs.yml
  43. 2
      fastapi/__init__.py
  44. 3
      fastapi/applications.py
  45. 30
      fastapi/concurrency.py
  46. 15
      fastapi/dependencies/utils.py
  47. 10
      fastapi/encoders.py
  48. 16
      fastapi/exception_handlers.py
  49. 4
      fastapi/routing.py
  50. 2
      fastapi/security/api_key.py
  51. 10
      fastapi/utils.py
  52. 1
      fastapi/websockets.py
  53. 66
      pyproject.toml
  54. 5
      scripts/docs.py
  55. 63
      tests/test_additional_responses_router.py
  56. 16
      tests/test_jsonable_encoder.py
  57. 97
      tests/test_reponse_set_reponse_code_empty.py
  58. 46
      tests/test_starlette_exception.py
  59. 10
      tests/test_tutorial/test_sql_databases_peewee/test_sql_databases_peewee.py
  60. 11
      tests/test_union_inherited_body.py
  61. 1
      tests/utils.py

4
.github/actions/people/app/main.py

@ -260,6 +260,7 @@ class Settings(BaseSettings):
input_token: SecretStr
input_standard_token: SecretStr
github_repository: str
httpx_timeout: int = 30
def get_graphql_response(
@ -270,9 +271,10 @@ def get_graphql_response(
response = httpx.post(
github_graphql_url,
headers=headers,
timeout=settings.httpx_timeout,
json={"query": query, "variables": variables, "operationName": "Q"},
)
if not response.status_code == 200:
if response.status_code != 200:
logging.error(f"Response was not 200, after: {after}")
logging.error(response.text)
raise RuntimeError(response.text)

7
.github/workflows/build-docs.yml

@ -23,17 +23,14 @@ jobs:
with:
path: ${{ env.pythonLocation }}
key: ${{ runner.os }}-python-docs-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-v03
- name: Install Flit
if: steps.cache.outputs.cache-hit != 'true'
run: python3.7 -m pip install flit
- name: Install docs extras
if: steps.cache.outputs.cache-hit != 'true'
run: python3.7 -m flit install --deps production --extras doc
run: pip install .[doc]
- name: Install Material for MkDocs Insiders
if: ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false ) && steps.cache.outputs.cache-hit != 'true'
run: pip install git+https://${{ secrets.ACTIONS_TOKEN }}@github.com/squidfunk/mkdocs-material-insiders.git
- name: Build Docs
run: python3.7 ./scripts/docs.py build-all
run: python ./scripts/docs.py build-all
- name: Zip docs
run: bash ./scripts/zip-docs.sh
- uses: actions/upload-artifact@v3

2
.github/workflows/preview-docs.yml

@ -12,7 +12,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Download Artifact Docs
uses: dawidd6/[email protected]2.0
uses: dawidd6/[email protected]3.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
workflow: build-docs.yml

18
.github/workflows/publish.yml

@ -17,23 +17,21 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.6"
python-version: "3.7"
- uses: actions/cache@v3
id: cache
with:
path: ${{ env.pythonLocation }}
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-publish
- name: Install Flit
- name: Install build dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: pip install flit
- name: Install Dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: flit install --symlink
run: pip install build
- name: Build distribution
run: python -m build
- name: Publish
env:
FLIT_USERNAME: ${{ secrets.FLIT_USERNAME }}
FLIT_PASSWORD: ${{ secrets.FLIT_PASSWORD }}
run: bash scripts/publish.sh
uses: pypa/[email protected]
with:
password: ${{ secrets.PYPI_API_TOKEN }}
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}

8
.github/workflows/test.yml

@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"]
python-version: ["3.7", "3.8", "3.9", "3.10"]
fail-fast: false
steps:
@ -26,14 +26,10 @@ jobs:
with:
path: ${{ env.pythonLocation }}
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-test-v02
- name: Install Flit
if: steps.cache.outputs.cache-hit != 'true'
run: pip install flit
- name: Install Dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: flit install --symlink
run: pip install -e .[all,dev,doc,test]
- name: Lint
if: ${{ matrix.python-version != '3.6' }}
run: bash scripts/lint.sh
- name: Test
run: bash scripts/test.sh

8
.pre-commit-config.yaml

@ -12,14 +12,14 @@ repos:
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/asottile/pyupgrade
rev: v2.37.3
rev: v3.1.0
hooks:
- id: pyupgrade
args:
- --py3-plus
- --keep-runtime-typing
- repo: https://github.com/myint/autoflake
rev: v1.4
- repo: https://github.com/PyCQA/autoflake
rev: v1.7.6
hooks:
- id: autoflake
args:
@ -43,7 +43,7 @@ repos:
name: isort (pyi)
types: [pyi]
- repo: https://github.com/psf/black
rev: 22.6.0
rev: 22.10.0
hooks:
- id: black
ci:

8
README.md

@ -27,7 +27,7 @@
---
FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.6+ based on standard Python type hints.
FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.7+ based on standard Python type hints.
The key features are:
@ -112,7 +112,7 @@ If you are building a <abbr title="Command Line Interface">CLI</abbr> app to be
## Requirements
Python 3.6+
Python 3.7+
FastAPI stands on the shoulders of giants:
@ -131,7 +131,7 @@ $ pip install fastapi
</div>
You will also need an ASGI server, for production such as <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> or <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>.
You will also need an ASGI server, for production such as <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> or <a href="https://github.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>.
<div class="termy">
@ -328,7 +328,7 @@ 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+**.
Just standard **Python 3.7+**.
For example, for an `int`:

2
SECURITY.md

@ -6,7 +6,7 @@ Learn more about it below. 👇
## Versions
The latest versions of FastAPI are supported.
The latest version of FastAPI is supported.
You are encouraged to [write tests](https://fastapi.tiangolo.com/tutorial/testing/) for your application and update your FastAPI version frequently after ensuring that your tests are passing. This way you will benefit from the latest features, bug fixes, and **security fixes**.

466
docs/az/docs/index.md

@ -0,0 +1,466 @@
{!../../../docs/missing-translation.md!}
<p align="center">
<a href="https://fastapi.tiangolo.com"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" alt="FastAPI"></a>
</p>
<p align="center">
<em>FastAPI framework, high performance, easy to learn, fast to code, ready for production</em>
</p>
<p align="center">
<a href="https://github.com/tiangolo/fastapi/actions?query=workflow%3ATest" target="_blank">
<img src="https://github.com/tiangolo/fastapi/workflows/Test/badge.svg" alt="Test">
</a>
<a href="https://codecov.io/gh/tiangolo/fastapi" target="_blank">
<img src="https://img.shields.io/codecov/c/github/tiangolo/fastapi?color=%2334D058" alt="Coverage">
</a>
<a href="https://pypi.org/project/fastapi" target="_blank">
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Package version">
</a>
</p>
---
**Documentation**: <a href="https://fastapi.tiangolo.com" target="_blank">https://fastapi.tiangolo.com</a>
**Source Code**: <a href="https://github.com/tiangolo/fastapi" target="_blank">https://github.com/tiangolo/fastapi</a>
---
FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.6+ based on standard Python type hints.
The key features are:
* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
* **Fast to code**: Increase the speed to develop features by about 200% to 300%. *
* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. *
* **Intuitive**: Great editor support. <abbr title="also known as auto-complete, autocompletion, IntelliSense">Completion</abbr> everywhere. Less time debugging.
* **Easy**: Designed to be easy to use and learn. Less time reading docs.
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
* **Robust**: Get production-ready code. With automatic interactive documentation.
* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (previously known as Swagger) and <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
<small>* estimation based on tests on an internal development team, building production applications.</small>
## Sponsors
<!-- sponsors -->
{% if sponsors %}
{% for sponsor in sponsors.gold -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor -%}
{%- for sponsor in sponsors.silver -%}
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor %}
{% endif %}
<!-- /sponsors -->
<a href="https://fastapi.tiangolo.com/fastapi-people/#sponsors" class="external-link" target="_blank">Other sponsors</a>
## Opinions
"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._"
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/tiangolo/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div>
---
"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_"
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div>
---
"_**Netflix** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_"
<div style="text-align: right; margin-right: 10%;">Kevin Glisson, Marc Vilanova, Forest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072" target="_blank"><small>(ref)</small></a></div>
---
"_I’m over the moon excited about **FastAPI**. It’s so fun!_"
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a> podcast host</strong> <a href="https://twitter.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
---
"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._"
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
---
"_If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]_"
"_We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]_"
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> founders - <a href="https://spacy.io" target="_blank">spaCy</a> creators</strong> <a href="https://twitter.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://twitter.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
---
## **Typer**, the FastAPI of CLIs
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
If you are building a <abbr title="Command Line Interface">CLI</abbr> app to be used in the terminal instead of a web API, check out <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>.
**Typer** is FastAPI's little sibling. And it's intended to be the **FastAPI of CLIs**. ⌨️ 🚀
## Requirements
Python 3.7+
FastAPI stands on the shoulders of giants:
* <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> for the web parts.
* <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> for the data parts.
## Installation
<div class="termy">
```console
$ pip install fastapi
---> 100%
```
</div>
You will also need an ASGI server, for production such as <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> or <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>.
<div class="termy">
```console
$ pip install "uvicorn[standard]"
---> 100%
```
</div>
## Example
### Create it
* Create a file `main.py` with:
```Python
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "q": q}
```
<details markdown="1">
<summary>Or use <code>async def</code>...</summary>
If your code uses `async` / `await`, use `async def`:
```Python hl_lines="9 14"
from typing import Optional
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "q": q}
```
**Note**:
If you don't know, check the _"In a hurry?"_ section about <a href="https://fastapi.tiangolo.com/async/#in-a-hurry" target="_blank">`async` and `await` in the docs</a>.
</details>
### Run it
Run the server with:
<div class="termy">
```console
$ uvicorn main:app --reload
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [28720]
INFO: Started server process [28722]
INFO: Waiting for application startup.
INFO: Application startup complete.
```
</div>
<details markdown="1">
<summary>About the command <code>uvicorn main:app --reload</code>...</summary>
The command `uvicorn main:app` refers to:
* `main`: the file `main.py` (the Python "module").
* `app`: the object created inside of `main.py` with the line `app = FastAPI()`.
* `--reload`: make the server restart after code changes. Only do this for development.
</details>
### Check it
Open your browser at <a href="http://127.0.0.1:8000/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1:8000/items/5?q=somequery</a>.
You will see the JSON response as:
```JSON
{"item_id": 5, "q": "somequery"}
```
You already created an API that:
* Receives HTTP requests in the _paths_ `/` and `/items/{item_id}`.
* Both _paths_ take `GET` <em>operations</em> (also known as HTTP _methods_).
* The _path_ `/items/{item_id}` has a _path parameter_ `item_id` that should be an `int`.
* The _path_ `/items/{item_id}` has an optional `str` _query parameter_ `q`.
### Interactive API docs
Now go to <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
You will see the automatic interactive API documentation (provided by <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
![Swagger UI](https://fastapi.tiangolo.com/img/index/index-01-swagger-ui-simple.png)
### Alternative API docs
And now, go to <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
You will see the alternative automatic documentation (provided by <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>):
![ReDoc](https://fastapi.tiangolo.com/img/index/index-02-redoc-simple.png)
## Example upgrade
Now modify the file `main.py` to receive a body from a `PUT` request.
Declare the body using standard Python types, thanks to Pydantic.
```Python hl_lines="4 9-12 25-27"
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: Optional[bool] = None
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Optional[str] = None):
return {"item_id": item_id, "q": q}
@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
return {"item_name": item.name, "item_id": item_id}
```
The server should reload automatically (because you added `--reload` to the `uvicorn` command above).
### Interactive API docs upgrade
Now go to <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
* The interactive API documentation will be automatically updated, including the new body:
![Swagger UI](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png)
* Click on the button "Try it out", it allows you to fill the parameters and directly interact with the API:
![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-04-swagger-03.png)
* Then click on the "Execute" button, the user interface will communicate with your API, send the parameters, get the results and show them on the screen:
![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-05-swagger-04.png)
### Alternative API docs upgrade
And now, go to <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
* The alternative documentation will also reflect the new query parameter and body:
![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png)
### Recap
In summary, you declare **once** the types of parameters, body, etc. as function parameters.
You do that with standard modern Python types.
You don't have to learn a new syntax, the methods or classes of a specific library, etc.
Just standard **Python 3.6+**.
For example, for an `int`:
```Python
item_id: int
```
or for a more complex `Item` model:
```Python
item: Item
```
...and with that single declaration you get:
* Editor support, including:
* Completion.
* Type checks.
* Validation of data:
* Automatic and clear errors when the data is invalid.
* Validation even for deeply nested JSON objects.
* <abbr title="also known as: serialization, parsing, marshalling">Conversion</abbr> of input data: coming from the network to Python data and types. Reading from:
* JSON.
* Path parameters.
* Query parameters.
* Cookies.
* Headers.
* Forms.
* Files.
* <abbr title="also known as: serialization, parsing, marshalling">Conversion</abbr> of output data: converting from Python data and types to network data (as JSON):
* Convert Python types (`str`, `int`, `float`, `bool`, `list`, etc).
* `datetime` objects.
* `UUID` objects.
* Database models.
* ...and many more.
* Automatic interactive API documentation, including 2 alternative user interfaces:
* Swagger UI.
* ReDoc.
---
Coming back to the previous code example, **FastAPI** will:
* Validate that there is an `item_id` in the path for `GET` and `PUT` requests.
* Validate that the `item_id` is of type `int` for `GET` and `PUT` requests.
* If it is not, the client will see a useful, clear error.
* Check if there is an optional query parameter named `q` (as in `http://127.0.0.1:8000/items/foo?q=somequery`) for `GET` requests.
* As the `q` parameter is declared with `= None`, it is optional.
* Without the `None` it would be required (as is the body in the case with `PUT`).
* For `PUT` requests to `/items/{item_id}`, Read the body as JSON:
* Check that it has a required attribute `name` that should be a `str`.
* Check that it has a required attribute `price` that has to be a `float`.
* Check that it has an optional attribute `is_offer`, that should be a `bool`, if present.
* All this would also work for deeply nested JSON objects.
* Convert from and to JSON automatically.
* Document everything with OpenAPI, that can be used by:
* Interactive documentation systems.
* Automatic client code generation systems, for many languages.
* Provide 2 interactive documentation web interfaces directly.
---
We just scratched the surface, but you already get the idea of how it all works.
Try changing the line with:
```Python
return {"item_name": item.name, "item_id": item_id}
```
...from:
```Python
... "item_name": item.name ...
```
...to:
```Python
... "item_price": item.price ...
```
...and see how your editor will auto-complete the attributes and know their types:
![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png)
For a more complete example including more features, see the <a href="https://fastapi.tiangolo.com/tutorial/">Tutorial - User Guide</a>.
**Spoiler alert**: the tutorial - user guide includes:
* Declaration of **parameters** from other different places as: **headers**, **cookies**, **form fields** and **files**.
* How to set **validation constraints** as `maximum_length` or `regex`.
* A very powerful and easy to use **<abbr title="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** system.
* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth.
* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic).
* Many extra features (thanks to Starlette) as:
* **WebSockets**
* **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="https://requests.readthedocs.io" target="_blank"><code>requests</code></a> - Required if you want to use the `TestClient`.
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`.
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Required for `SessionMiddleware` support.
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Required for Starlette's `SchemaGenerator` support (you probably don't need it with FastAPI).
* <a href="https://graphene-python.org/" target="_blank"><code>graphene</code></a> - Required for `GraphQLApp` support.
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Required if you want to use `UJSONResponse`.
Used by FastAPI / Starlette:
* <a href="https://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - for the server that loads and serves your application.
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - Required if you want to use `ORJSONResponse`.
You can install all of these with `pip install fastapi[all]`.
## License
This project is licensed under the terms of the MIT license.

2
docs/de/docs/index.md

@ -111,7 +111,7 @@ If you are building a <abbr title="Command Line Interface">CLI</abbr> app to be
## Requirements
Python 3.6+
Python 3.7+
FastAPI stands on the shoulders of giants:

8
docs/en/data/external_links.yml

@ -1,5 +1,13 @@
articles:
english:
- author: WayScript
author_link: https://www.wayscript.com
link: https://blog.wayscript.com/fast-api-quickstart/
title: Quickstart Guide to Build and Host Responsive APIs with Fast API and WayScript
- author: New Relic
author_link: https://newrelic.com
link: https://newrelic.com/instant-observability/fastapi/e559ec64-f765-4470-a15f-1901fcebb468
title: How to monitor FastAPI application performance using Python agent
- author: Jean-Baptiste Rocher
author_link: https://hashnode.com/@jibrocher
link: https://dev.indooroutdoor.io/series/fastapi-react-poll-app

232
docs/en/data/github_sponsors.yml

@ -1,34 +1,25 @@
sponsors:
- - login: github
avatarUrl: https://avatars.githubusercontent.com/u/9919?v=4
url: https://github.com/github
- - login: jina-ai
avatarUrl: https://avatars.githubusercontent.com/u/60539444?v=4
url: https://github.com/jina-ai
- - login: Doist
avatarUrl: https://avatars.githubusercontent.com/u/2565372?v=4
url: https://github.com/Doist
- login: cryptapi
avatarUrl: https://avatars.githubusercontent.com/u/44925437?u=61369138589bc7fee6c417f3fbd50fbd38286cc4&v=4
url: https://github.com/cryptapi
- login: BLUE-DEVIL1134
avatarUrl: https://avatars.githubusercontent.com/u/55914808?u=f283d674fce31be7fb3ed2665b0f20d89958e541&v=4
url: https://github.com/BLUE-DEVIL1134
- login: jina-ai
avatarUrl: https://avatars.githubusercontent.com/u/60539444?v=4
url: https://github.com/jina-ai
- login: DropbaseHQ
avatarUrl: https://avatars.githubusercontent.com/u/85367855?v=4
url: https://github.com/DropbaseHQ
- - login: ObliviousAI
avatarUrl: https://avatars.githubusercontent.com/u/65656077?v=4
url: https://github.com/ObliviousAI
- login: Lovage-Labs
avatarUrl: https://avatars.githubusercontent.com/u/71685552?v=4
url: https://github.com/Lovage-Labs
- login: chaserowbotham
avatarUrl: https://avatars.githubusercontent.com/u/97751084?v=4
url: https://github.com/chaserowbotham
- - login: mikeckennedy
avatarUrl: https://avatars.githubusercontent.com/u/2035561?u=1bb18268bcd4d9249e1f783a063c27df9a84c05b&v=4
url: https://github.com/mikeckennedy
- login: Trivie
avatarUrl: https://avatars.githubusercontent.com/u/8161763?v=4
url: https://github.com/Trivie
- login: deta
avatarUrl: https://avatars.githubusercontent.com/u/47275976?v=4
url: https://github.com/deta
@ -44,12 +35,15 @@ sponsors:
- - login: InesIvanova
avatarUrl: https://avatars.githubusercontent.com/u/22920417?u=409882ec1df6dbd77455788bb383a8de223dbf6f&v=4
url: https://github.com/InesIvanova
- - login: SendCloud
- - login: zopyx
avatarUrl: https://avatars.githubusercontent.com/u/594239?u=8e5ce882664f47fd61002bed51718c78c3799d24&v=4
url: https://github.com/zopyx
- login: SendCloud
avatarUrl: https://avatars.githubusercontent.com/u/7831959?v=4
url: https://github.com/SendCloud
- login: qaas
avatarUrl: https://avatars.githubusercontent.com/u/8503759?u=10a6b4391ad6ab4cf9487ce54e3fcb61322d1efc&v=4
url: https://github.com/qaas
- login: mercedes-benz
avatarUrl: https://avatars.githubusercontent.com/u/34240465?v=4
url: https://github.com/mercedes-benz
- login: xoflare
avatarUrl: https://avatars.githubusercontent.com/u/74335107?v=4
url: https://github.com/xoflare
@ -59,15 +53,15 @@ sponsors:
- login: BoostryJP
avatarUrl: https://avatars.githubusercontent.com/u/57932412?v=4
url: https://github.com/BoostryJP
- - login: nnfuzzy
avatarUrl: https://avatars.githubusercontent.com/u/687670?v=4
url: https://github.com/nnfuzzy
- login: johnadjei
- - login: johnadjei
avatarUrl: https://avatars.githubusercontent.com/u/767860?v=4
url: https://github.com/johnadjei
- login: HiredScore
avatarUrl: https://avatars.githubusercontent.com/u/3908850?v=4
url: https://github.com/HiredScore
- login: Trivie
avatarUrl: https://avatars.githubusercontent.com/u/8161763?v=4
url: https://github.com/Trivie
- login: wdwinslow
avatarUrl: https://avatars.githubusercontent.com/u/11562137?u=dc01daafb354135603a263729e3d26d939c0c452&v=4
url: https://github.com/wdwinslow
@ -80,27 +74,30 @@ sponsors:
- login: tizz98
avatarUrl: https://avatars.githubusercontent.com/u/5739698?u=f095a3659e3a8e7c69ccd822696990b521ea25f9&v=4
url: https://github.com/tizz98
- login: Vikka
avatarUrl: https://avatars.githubusercontent.com/u/9381120?u=4bfc7032a824d1ed1994aa8256dfa597c8f187ad&v=4
url: https://github.com/Vikka
- login: jmaralc
avatarUrl: https://avatars.githubusercontent.com/u/21101214?u=b15a9f07b7cbf6c9dcdbcb6550bbd2c52f55aa50&v=4
url: https://github.com/jmaralc
- login: marutoraman
- login: takashi-yoneya
avatarUrl: https://avatars.githubusercontent.com/u/33813153?u=2d0522bceba0b8b69adf1f2db866503bd96f944e&v=4
url: https://github.com/marutoraman
- login: leynier
avatarUrl: https://avatars.githubusercontent.com/u/36774373?u=2284831c821307de562ebde5b59014d5416c7e0d&v=4
url: https://github.com/leynier
url: https://github.com/takashi-yoneya
- login: mainframeindustries
avatarUrl: https://avatars.githubusercontent.com/u/55092103?v=4
url: https://github.com/mainframeindustries
- login: A-Edge
avatarUrl: https://avatars.githubusercontent.com/u/59514131?v=4
url: https://github.com/A-Edge
- login: DelfinaCare
avatarUrl: https://avatars.githubusercontent.com/u/83734439?v=4
url: https://github.com/DelfinaCare
- - login: povilasb
avatarUrl: https://avatars.githubusercontent.com/u/1213442?u=b11f58ed6ceea6e8297c9b310030478ebdac894d&v=4
url: https://github.com/povilasb
- login: primer-io
avatarUrl: https://avatars.githubusercontent.com/u/62146168?v=4
url: https://github.com/primer-io
- - login: A-Edge
avatarUrl: https://avatars.githubusercontent.com/u/59514131?v=4
url: https://github.com/A-Edge
- - login: Kludex
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex
@ -116,6 +113,12 @@ sponsors:
- login: kamalgill
avatarUrl: https://avatars.githubusercontent.com/u/133923?u=0df9181d97436ce330e9acf90ab8a54b7022efe7&v=4
url: https://github.com/kamalgill
- login: dekoza
avatarUrl: https://avatars.githubusercontent.com/u/210980?u=c03c78a8ae1039b500dfe343665536ebc51979b2&v=4
url: https://github.com/dekoza
- login: pamelafox
avatarUrl: https://avatars.githubusercontent.com/u/297042?v=4
url: https://github.com/pamelafox
- login: deserat
avatarUrl: https://avatars.githubusercontent.com/u/299332?v=4
url: https://github.com/deserat
@ -128,6 +131,9 @@ sponsors:
- login: koxudaxi
avatarUrl: https://avatars.githubusercontent.com/u/630670?u=507d8577b4b3670546b449c4c2ccbc5af40d72f7&v=4
url: https://github.com/koxudaxi
- login: falkben
avatarUrl: https://avatars.githubusercontent.com/u/653031?u=0c8d8f33d87f1aa1a6488d3f02105e9abc838105&v=4
url: https://github.com/falkben
- login: jqueguiner
avatarUrl: https://avatars.githubusercontent.com/u/690878?u=bd65cc1f228ce6455e56dfaca3ef47c33bc7c3b0&v=4
url: https://github.com/jqueguiner
@ -164,12 +170,21 @@ sponsors:
- login: zsinx6
avatarUrl: https://avatars.githubusercontent.com/u/3532625?u=ba75a5dc744d1116ccfeaaf30d41cb2fe81fe8dd&v=4
url: https://github.com/zsinx6
- login: MarekBleschke
avatarUrl: https://avatars.githubusercontent.com/u/3616870?v=4
url: https://github.com/MarekBleschke
- login: aacayaco
avatarUrl: https://avatars.githubusercontent.com/u/3634801?u=eaadda178c964178fcb64886f6c732172c8f8219&v=4
url: https://github.com/aacayaco
- login: anomaly
avatarUrl: https://avatars.githubusercontent.com/u/3654837?v=4
url: https://github.com/anomaly
- login: peterHoburg
avatarUrl: https://avatars.githubusercontent.com/u/3860655?u=f55f47eb2d6a9b495e806ac5a044e3ae01ccc1fa&v=4
url: https://github.com/peterHoburg
- login: jgreys
avatarUrl: https://avatars.githubusercontent.com/u/4136890?u=b579fd97033269a5e703ab509c7d5478b146cc2d&v=4
url: https://github.com/jgreys
- login: gorhack
avatarUrl: https://avatars.githubusercontent.com/u/4141690?u=ec119ebc4bdf00a7bc84657a71aa17834f4f27f3&v=4
url: https://github.com/gorhack
@ -188,14 +203,11 @@ sponsors:
- login: ennui93
avatarUrl: https://avatars.githubusercontent.com/u/5300907?u=5b5452725ddb391b2caaebf34e05aba873591c3a&v=4
url: https://github.com/ennui93
- login: MacroPower
avatarUrl: https://avatars.githubusercontent.com/u/5648814?u=e13991efd1e03c44c911f919872e750530ded633&v=4
url: https://github.com/MacroPower
- login: Yaleesa
avatarUrl: https://avatars.githubusercontent.com/u/6135475?v=4
url: https://github.com/Yaleesa
- login: iwpnd
avatarUrl: https://avatars.githubusercontent.com/u/6152183?u=b2286006daafff5f991557344fee20b5da59639a&v=4
avatarUrl: https://avatars.githubusercontent.com/u/6152183?u=c485eefca5c6329600cae63dd35e4f5682ce6924&v=4
url: https://github.com/iwpnd
- login: simw
avatarUrl: https://avatars.githubusercontent.com/u/6322526?v=4
@ -203,9 +215,6 @@ sponsors:
- login: pkucmus
avatarUrl: https://avatars.githubusercontent.com/u/6347418?u=98f5918b32e214a168a2f5d59b0b8ebdf57dca0d&v=4
url: https://github.com/pkucmus
- login: ioalloc
avatarUrl: https://avatars.githubusercontent.com/u/6737824?u=6c3a31449f1c92064287171aa9ebe6363a0c9b7b&v=4
url: https://github.com/ioalloc
- login: s3ich4n
avatarUrl: https://avatars.githubusercontent.com/u/6926298?u=ba3025d698e1c986655e776ae383a3d60d9d578e&v=4
url: https://github.com/s3ich4n
@ -218,9 +227,6 @@ sponsors:
- login: Shackelford-Arden
avatarUrl: https://avatars.githubusercontent.com/u/7362263?v=4
url: https://github.com/Shackelford-Arden
- login: Vikka
avatarUrl: https://avatars.githubusercontent.com/u/9381120?u=4bfc7032a824d1ed1994aa8256dfa597c8f187ad&v=4
url: https://github.com/Vikka
- login: Ge0f3
avatarUrl: https://avatars.githubusercontent.com/u/11887760?u=ccd80f1ac36dcb8517ef5c4e702e8cc5a80cad2f&v=4
url: https://github.com/Ge0f3
@ -242,9 +248,6 @@ sponsors:
- login: wedwardbeck
avatarUrl: https://avatars.githubusercontent.com/u/19333237?u=1de4ae2bf8d59eb4c013f21d863cbe0f2010575f&v=4
url: https://github.com/wedwardbeck
- login: stradivari96
avatarUrl: https://avatars.githubusercontent.com/u/19752586?u=255f5f06a768f518b20cebd6963e840ac49294fd&v=4
url: https://github.com/stradivari96
- login: RedCarpetUp
avatarUrl: https://avatars.githubusercontent.com/u/20360440?v=4
url: https://github.com/RedCarpetUp
@ -266,33 +269,30 @@ sponsors:
- login: veprimk
avatarUrl: https://avatars.githubusercontent.com/u/29689749?u=f8cb5a15a286e522e5b189bc572d5a1a90217fb2&v=4
url: https://github.com/veprimk
- login: meysam81
avatarUrl: https://avatars.githubusercontent.com/u/30233243?u=64dc9fc62d039892c6fb44d804251cad5537132b&v=4
url: https://github.com/meysam81
- login: BrettskiPy
avatarUrl: https://avatars.githubusercontent.com/u/30988215?u=d8a94a67e140d5ee5427724b292cc52d8827087a&v=4
url: https://github.com/BrettskiPy
- login: mauroalejandrojm
avatarUrl: https://avatars.githubusercontent.com/u/31569442?u=cdada990a1527926a36e95f62c30a8b48bbc49a1&v=4
url: https://github.com/mauroalejandrojm
- login: Leay15
avatarUrl: https://avatars.githubusercontent.com/u/32212558?u=c4aa9c1737e515959382a5515381757b1fd86c53&v=4
url: https://github.com/Leay15
- login: ygorpontelo
avatarUrl: https://avatars.githubusercontent.com/u/32963605?u=35f7103f9c4c4c2589ae5737ee882e9375ef072e&v=4
url: https://github.com/ygorpontelo
- login: AlrasheedA
avatarUrl: https://avatars.githubusercontent.com/u/33544979?u=7fe66bf62b47682612b222e3e8f4795ef3be769b&v=4
url: https://github.com/AlrasheedA
- login: ProteinQure
avatarUrl: https://avatars.githubusercontent.com/u/33707203?v=4
url: https://github.com/ProteinQure
- login: guligon90
avatarUrl: https://avatars.githubusercontent.com/u/35070513?u=b48c05f669d1ea1d329f90dc70e45f10b569ef55&v=4
url: https://github.com/guligon90
- login: ybressler
avatarUrl: https://avatars.githubusercontent.com/u/40807730?u=41e2c00f1eebe3c402635f0325e41b4e6511462c&v=4
url: https://github.com/ybressler
- login: ddilidili
avatarUrl: https://avatars.githubusercontent.com/u/42176885?u=c0a849dde06987434653197b5f638d3deb55fc6c&v=4
url: https://github.com/ddilidili
- login: dbanty
avatarUrl: https://avatars.githubusercontent.com/u/43723790?u=9bcce836bbce55835291c5b2ac93a4e311f4b3c3&v=4
url: https://github.com/dbanty
- login: VictorCalderon
avatarUrl: https://avatars.githubusercontent.com/u/44529243?u=cea69884f826a29aff1415493405209e0706d07a&v=4
url: https://github.com/VictorCalderon
@ -302,27 +302,27 @@ sponsors:
- login: rafsaf
avatarUrl: https://avatars.githubusercontent.com/u/51059348?u=f8f0d6d6e90fac39fa786228158ba7f013c74271&v=4
url: https://github.com/rafsaf
- login: yezz123
avatarUrl: https://avatars.githubusercontent.com/u/52716203?u=636b4f79645176df4527dd45c12d5dbb5a4193cf&v=4
url: https://github.com/yezz123
- login: dudikbender
avatarUrl: https://avatars.githubusercontent.com/u/53487583?u=494f85229115076121b3639a3806bbac1c6ae7f6&v=4
url: https://github.com/dudikbender
- login: daisuke8000
avatarUrl: https://avatars.githubusercontent.com/u/55035595?u=23a3f2f2925ad3efc27c7420041622b7f5fd2b79&v=4
url: https://github.com/daisuke8000
- login: dazeddd
avatarUrl: https://avatars.githubusercontent.com/u/59472056?u=7a1b668449bf8b448db13e4c575576d24d7d658b&v=4
url: https://github.com/dazeddd
- login: llamington
avatarUrl: https://avatars.githubusercontent.com/u/54869395?u=42ea59b76f49449f41a4d106bb65a130797e8d7c&v=4
url: https://github.com/llamington
- login: yakkonaut
avatarUrl: https://avatars.githubusercontent.com/u/60633704?u=90a71fd631aa998ba4a96480788f017c9904e07b&v=4
url: https://github.com/yakkonaut
- login: primer-io
avatarUrl: https://avatars.githubusercontent.com/u/62146168?v=4
url: https://github.com/primer-io
- login: around
avatarUrl: https://avatars.githubusercontent.com/u/62425723?v=4
url: https://github.com/around
- login: patsatsia
avatarUrl: https://avatars.githubusercontent.com/u/61111267?u=419516384f798a35e9d9e2dd81282cc46c151b58&v=4
url: https://github.com/patsatsia
- login: predictionmachine
avatarUrl: https://avatars.githubusercontent.com/u/63719559?v=4
url: https://github.com/predictionmachine
- login: minsau
avatarUrl: https://avatars.githubusercontent.com/u/64386242?u=7e45f24b2958caf946fa3546ea33bacf5cd886f8&v=4
url: https://github.com/minsau
- login: daverin
avatarUrl: https://avatars.githubusercontent.com/u/70378377?u=6d1814195c0de7162820eaad95a25b423a3869c0&v=4
url: https://github.com/daverin
@ -339,7 +339,7 @@ sponsors:
avatarUrl: https://avatars.githubusercontent.com/u/46711?v=4
url: https://github.com/linux-china
- login: ddanier
avatarUrl: https://avatars.githubusercontent.com/u/113563?v=4
avatarUrl: https://avatars.githubusercontent.com/u/113563?u=ed1dc79de72f93bd78581f88ebc6952b62f472da&v=4
url: https://github.com/ddanier
- login: jhb
avatarUrl: https://avatars.githubusercontent.com/u/142217?v=4
@ -350,8 +350,11 @@ sponsors:
- login: bryanculbertson
avatarUrl: https://avatars.githubusercontent.com/u/144028?u=defda4f90e93429221cc667500944abde60ebe4a&v=4
url: https://github.com/bryanculbertson
- login: hhatto
avatarUrl: https://avatars.githubusercontent.com/u/150309?u=3e8f63c27bf996bfc68464b0ce3f7a3e40e6ea7f&v=4
url: https://github.com/hhatto
- login: yourkin
avatarUrl: https://avatars.githubusercontent.com/u/178984?u=fa7c3503b47bf16405b96d21554bc59f07a65523&v=4
avatarUrl: https://avatars.githubusercontent.com/u/178984?u=b43a7e5f8818f7d9083d3b110118d9c27d48a794&v=4
url: https://github.com/yourkin
- login: slafs
avatarUrl: https://avatars.githubusercontent.com/u/210173?v=4
@ -369,14 +372,11 @@ sponsors:
avatarUrl: https://avatars.githubusercontent.com/u/388564?v=4
url: https://github.com/dmig
- login: rinckd
avatarUrl: https://avatars.githubusercontent.com/u/546002?u=1fcc7e664dc86524a0af6837a0c222829c3fd4e5&v=4
avatarUrl: https://avatars.githubusercontent.com/u/546002?u=8ec88ab721a5636346f19dcd677a6f323058be8b&v=4
url: https://github.com/rinckd
- login: securancy
avatarUrl: https://avatars.githubusercontent.com/u/606673?v=4
url: https://github.com/securancy
- login: falkben
avatarUrl: https://avatars.githubusercontent.com/u/653031?u=0c8d8f33d87f1aa1a6488d3f02105e9abc838105&v=4
url: https://github.com/falkben
- login: hardbyte
avatarUrl: https://avatars.githubusercontent.com/u/855189?u=aa29e92f34708814d6b67fcd47ca4cf2ce1c04ed&v=4
url: https://github.com/hardbyte
@ -384,16 +384,16 @@ sponsors:
avatarUrl: https://avatars.githubusercontent.com/u/861044?u=5abfca5588f3e906b31583d7ee62f6de4b68aa24&v=4
url: https://github.com/browniebroke
- login: janfilips
avatarUrl: https://avatars.githubusercontent.com/u/870699?u=6034d81731ecb41ae5c717e56a901ed46fc039a8&v=4
avatarUrl: https://avatars.githubusercontent.com/u/870699?u=50de77b93d3a0b06887e672d4e8c7b9d643085aa&v=4
url: https://github.com/janfilips
- login: woodrad
avatarUrl: https://avatars.githubusercontent.com/u/1410765?u=86707076bb03d143b3b11afc1743d2aa496bd8bf&v=4
url: https://github.com/woodrad
- login: Pytlicek
avatarUrl: https://avatars.githubusercontent.com/u/1430522?u=169dba3bfbc04ed214a914640ff435969f19ddb3&v=4
avatarUrl: https://avatars.githubusercontent.com/u/1430522?u=01b1f2f7671ce3131e0877d08e2e3f8bdbb0a38a&v=4
url: https://github.com/Pytlicek
- login: allen0125
avatarUrl: https://avatars.githubusercontent.com/u/1448456?u=d4feb3d06a61baa4a69857ce371cc53fb4dffd2c&v=4
avatarUrl: https://avatars.githubusercontent.com/u/1448456?u=dc2ad819497eef494b88688a1796e0adb87e7cae&v=4
url: https://github.com/allen0125
- login: WillHogan
avatarUrl: https://avatars.githubusercontent.com/u/1661551?u=7036c064cf29781470573865264ec8e60b6b809f&v=4
@ -401,9 +401,9 @@ sponsors:
- login: cbonoz
avatarUrl: https://avatars.githubusercontent.com/u/2351087?u=fd3e8030b2cc9fbfbb54a65e9890c548a016f58b&v=4
url: https://github.com/cbonoz
- login: rglsk
avatarUrl: https://avatars.githubusercontent.com/u/2768101?u=e349c88673f2155fe021331377c656a9d74bcc25&v=4
url: https://github.com/rglsk
- login: Debakel
avatarUrl: https://avatars.githubusercontent.com/u/2857237?u=07df6d11c8feef9306d071cb1c1005a2dd596585&v=4
url: https://github.com/Debakel
- login: paul121
avatarUrl: https://avatars.githubusercontent.com/u/3116995?u=6e2d8691cc345e63ee02e4eb4d7cef82b1fcbedc&v=4
url: https://github.com/paul121
@ -413,6 +413,9 @@ sponsors:
- login: anthonycorletti
avatarUrl: https://avatars.githubusercontent.com/u/3477132?v=4
url: https://github.com/anthonycorletti
- login: jonathanhle
avatarUrl: https://avatars.githubusercontent.com/u/3851599?u=76b9c5d2fecd6c3a16e7645231878c4507380d4d&v=4
url: https://github.com/jonathanhle
- login: pawamoy
avatarUrl: https://avatars.githubusercontent.com/u/3999221?u=b030e4c89df2f3a36bc4710b925bdeb6745c9856&v=4
url: https://github.com/pawamoy
@ -425,15 +428,18 @@ sponsors:
- login: unredundant
avatarUrl: https://avatars.githubusercontent.com/u/5607577?u=57dd0023365bec03f4fc566df6b81bc0a264a47d&v=4
url: https://github.com/unredundant
- login: Baghdady92
avatarUrl: https://avatars.githubusercontent.com/u/5708590?v=4
url: https://github.com/Baghdady92
- login: holec
avatarUrl: https://avatars.githubusercontent.com/u/6438041?u=f5af71ec85b3a9d7b8139cb5af0512b02fa9ab1e&v=4
url: https://github.com/holec
- login: hcristea
avatarUrl: https://avatars.githubusercontent.com/u/7814406?u=61d7a4fcf846983a4606788eac25e1c6c1209ba8&v=4
url: https://github.com/hcristea
- login: moonape1226
avatarUrl: https://avatars.githubusercontent.com/u/8532038?u=d9f8b855a429fff9397c3833c2ff83849ebf989d&v=4
url: https://github.com/moonape1226
- login: davanstrien
avatarUrl: https://avatars.githubusercontent.com/u/8995957?u=fb2aad2b52bb4e7b56db6d7c8ecc9ae1eac1b984&v=4
url: https://github.com/davanstrien
- login: yenchenLiu
avatarUrl: https://avatars.githubusercontent.com/u/9199638?u=8cdf5ae507448430d90f6f3518d1665a23afe99b&v=4
url: https://github.com/yenchenLiu
@ -449,17 +455,23 @@ sponsors:
- login: satwikkansal
avatarUrl: https://avatars.githubusercontent.com/u/10217535?u=b12d6ef74ea297de9e46da6933b1a5b7ba9e6a61&v=4
url: https://github.com/satwikkansal
- login: mntolia
avatarUrl: https://avatars.githubusercontent.com/u/10390224?v=4
url: https://github.com/mntolia
- login: pheanex
avatarUrl: https://avatars.githubusercontent.com/u/10408624?u=5b6bab6ee174aa6e991333e06eb29f628741013d&v=4
url: https://github.com/pheanex
- login: JimFawkes
avatarUrl: https://avatars.githubusercontent.com/u/12075115?u=dc58ecfd064d72887c34bf500ddfd52592509acd&v=4
url: https://github.com/JimFawkes
- login: giuliano-oliveira
avatarUrl: https://avatars.githubusercontent.com/u/13181797?u=0ef2dfbf7fc9a9726d45c21d32b5d1038a174870&v=4
url: https://github.com/giuliano-oliveira
- login: logan-connolly
avatarUrl: https://avatars.githubusercontent.com/u/16244943?u=8ae66dfbba936463cc8aa0dd7a6d2b4c0cc757eb&v=4
url: https://github.com/logan-connolly
- login: sanghunka
avatarUrl: https://avatars.githubusercontent.com/u/16280020?u=960f5426ae08303229f045b9cc2ed463dcd41c15&v=4
avatarUrl: https://avatars.githubusercontent.com/u/16280020?u=7d8fafd8bfe6d7900bb1e52d5a5d5da0c02bc164&v=4
url: https://github.com/sanghunka
- login: stevenayers
avatarUrl: https://avatars.githubusercontent.com/u/16361214?u=098b797d8d48afb8cd964b717847943b61d24a6d&v=4
@ -467,12 +479,12 @@ sponsors:
- login: cdsre
avatarUrl: https://avatars.githubusercontent.com/u/16945936?v=4
url: https://github.com/cdsre
- login: aprilcoskun
avatarUrl: https://avatars.githubusercontent.com/u/17393603?u=29145243b4c7fadc80c7099471309cc2c04b6bcc&v=4
url: https://github.com/aprilcoskun
- login: jangia
avatarUrl: https://avatars.githubusercontent.com/u/17927101?u=9261b9bb0c3e3bb1ecba43e8915dc58d8c9a077e&v=4
url: https://github.com/jangia
- login: paulowiz
avatarUrl: https://avatars.githubusercontent.com/u/18649504?u=d8a6ac40321f2bded0eba78b637751c7f86c6823&v=4
url: https://github.com/paulowiz
- login: yannicschroeer
avatarUrl: https://avatars.githubusercontent.com/u/22749683?u=4df05a7296c207b91c5d7c7a11c29df5ab313e2b&v=4
url: https://github.com/yannicschroeer
@ -485,15 +497,12 @@ sponsors:
- login: mertguvencli
avatarUrl: https://avatars.githubusercontent.com/u/29762151?u=16a906d90df96c8cff9ea131a575c4bc171b1523&v=4
url: https://github.com/mertguvencli
- login: elisoncrum
avatarUrl: https://avatars.githubusercontent.com/u/30413278?u=531190845bb0935dbc1e4f017cda3cb7b4dd0e54&v=4
url: https://github.com/elisoncrum
- login: ruizdiazever
avatarUrl: https://avatars.githubusercontent.com/u/29817086?u=2df54af55663d246e3a4dc8273711c37f1adb117&v=4
url: https://github.com/ruizdiazever
- login: HosamAlmoghraby
avatarUrl: https://avatars.githubusercontent.com/u/32025281?u=aa1b09feabccbf9dc506b81c71155f32d126cefa&v=4
url: https://github.com/HosamAlmoghraby
- login: kitaramu0401
avatarUrl: https://avatars.githubusercontent.com/u/33246506?u=929e6efa2c518033b8097ba524eb5347a069bb3b&v=4
url: https://github.com/kitaramu0401
- login: engineerjoe440
avatarUrl: https://avatars.githubusercontent.com/u/33275230?u=eb223cad27017bb1e936ee9b429b450d092d0236&v=4
url: https://github.com/engineerjoe440
@ -501,7 +510,7 @@ sponsors:
avatarUrl: https://avatars.githubusercontent.com/u/36180226?v=4
url: https://github.com/declon
- login: alvarobartt
avatarUrl: https://avatars.githubusercontent.com/u/36760800?u=ac9ccb8b9164eb5fe7d5276142591aa1b8080daf&v=4
avatarUrl: https://avatars.githubusercontent.com/u/36760800?u=9b38695807eb981d452989699ff72ec2d8f6508e&v=4
url: https://github.com/alvarobartt
- login: d-e-h-i-o
avatarUrl: https://avatars.githubusercontent.com/u/36816716?v=4
@ -516,11 +525,14 @@ sponsors:
avatarUrl: https://avatars.githubusercontent.com/u/42189572?u=a2d6121bac4d125d92ec207460fa3f1842d37e66&v=4
url: https://github.com/ilias-ant
- login: arrrrrmin
avatarUrl: https://avatars.githubusercontent.com/u/43553423?u=fee5739394fea074cb0b66929d070114a5067aae&v=4
avatarUrl: https://avatars.githubusercontent.com/u/43553423?u=2a812c1a2ec58227ed01778837f255143de9df97&v=4
url: https://github.com/arrrrrmin
- login: BomGard
avatarUrl: https://avatars.githubusercontent.com/u/47395385?u=8e9052f54e0b8dc7285099c438fa29c55a7d6407&v=4
url: https://github.com/BomGard
- login: MauriceKuenicke
avatarUrl: https://avatars.githubusercontent.com/u/47433175?u=37455bc95c7851db296ac42626f0cacb77ca2443&v=4
url: https://github.com/MauriceKuenicke
- login: hgalytoby
avatarUrl: https://avatars.githubusercontent.com/u/50397689?u=f4888c2c54929bd86eed0d3971d09fcb306e5088&v=4
url: https://github.com/hgalytoby
- login: akanz1
avatarUrl: https://avatars.githubusercontent.com/u/51492342?u=2280f57134118714645e16b535c1a37adf6b369b&v=4
url: https://github.com/akanz1
@ -548,24 +560,24 @@ sponsors:
- login: alessio-proietti
avatarUrl: https://avatars.githubusercontent.com/u/67370599?u=8ac73db1e18e946a7681f173abdb640516f88515&v=4
url: https://github.com/alessio-proietti
- login: Mr-Sunglasses
avatarUrl: https://avatars.githubusercontent.com/u/81439109?u=a5d0762fdcec26e18a028aef05323de3c6fb195c&v=4
url: https://github.com/Mr-Sunglasses
- - login: backbord
avatarUrl: https://avatars.githubusercontent.com/u/6814946?v=4
url: https://github.com/backbord
- login: pondDevThai
avatarUrl: https://avatars.githubusercontent.com/u/71592181?u=08af9a59bccfd8f6b101de1005aa9822007d0a44&v=4
url: https://github.com/pondDevThai
- - login: mattwelke
avatarUrl: https://avatars.githubusercontent.com/u/7719209?u=5d963ead289969257190b133250653bd99df06ba&v=4
url: https://github.com/mattwelke
- login: cesarfreire
avatarUrl: https://avatars.githubusercontent.com/u/21126103?u=5d428f77f9b63c741f0e9ca5e15a689017b66fe8&v=4
url: https://github.com/cesarfreire
- login: gabrielmbmb
avatarUrl: https://avatars.githubusercontent.com/u/29572918?u=6d1e00b5d558e96718312ff910a2318f47cc3145&v=4
url: https://github.com/gabrielmbmb
- login: danburonline
avatarUrl: https://avatars.githubusercontent.com/u/34251194?u=2cad4388c1544e539ecb732d656e42fb07b4ff2d&v=4
url: https://github.com/danburonline
- login: zachspar
avatarUrl: https://avatars.githubusercontent.com/u/41600414?u=edf29c197137f51bace3f19a2ba759662640771f&v=4
url: https://github.com/zachspar
- login: sownt
avatarUrl: https://avatars.githubusercontent.com/u/44340502?u=c06e3c45fb00a403075172770805fe57ff17b1cf&v=4
url: https://github.com/sownt
- login: aahouzi
avatarUrl: https://avatars.githubusercontent.com/u/75032370?u=82677ee9cd86b3ccf4e13d9cb6765d8de5713e1e&v=4
url: https://github.com/aahouzi
- login: Moises6669
avatarUrl: https://avatars.githubusercontent.com/u/66188523?u=96af25b8d5be9f983cb96e9dd7c605c716caf1f5&v=4
url: https://github.com/Moises6669
- login: zahariev-webbersof
avatarUrl: https://avatars.githubusercontent.com/u/68993494?u=b341c94a8aa0624e05e201bcf8ae5b2697e3be2f&v=4
url: https://github.com/zahariev-webbersof

222
docs/en/data/people.yml

@ -1,12 +1,12 @@
maintainers:
- login: tiangolo
answers: 1248
prs: 318
answers: 1271
prs: 338
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=740f11212a731f56798f558ceddb0bd07642afa7&v=4
url: https://github.com/tiangolo
experts:
- login: Kludex
count: 352
count: 364
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex
- login: dmontagu
@ -15,7 +15,7 @@ experts:
url: https://github.com/dmontagu
- login: ycd
count: 221
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=826f228edf0bab0d19ad1d5c4ba4df1047ccffef&v=4
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=fa40e037060d62bf82e16b505d870a2866725f38&v=4
url: https://github.com/ycd
- login: Mause
count: 207
@ -25,6 +25,10 @@ experts:
count: 166
avatarUrl: https://avatars.githubusercontent.com/u/1104190?u=321a2e953e6645a7d09b732786c7a8061e0f8a8b&v=4
url: https://github.com/euri10
- login: JarroVGIT
count: 163
avatarUrl: https://avatars.githubusercontent.com/u/13659033?u=e8bea32d07a5ef72f7dde3b2079ceb714923ca05&v=4
url: https://github.com/JarroVGIT
- login: phy25
count: 130
avatarUrl: https://avatars.githubusercontent.com/u/331403?v=4
@ -37,10 +41,10 @@ experts:
count: 71
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=b0f2c37142f4b762e41ad65dc49581813422bd71&v=4
url: https://github.com/ArcLightSlavik
- login: JarroVGIT
count: 68
avatarUrl: https://avatars.githubusercontent.com/u/13659033?u=e8bea32d07a5ef72f7dde3b2079ceb714923ca05&v=4
url: https://github.com/JarroVGIT
- login: iudeen
count: 65
avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4
url: https://github.com/iudeen
- login: falkben
count: 58
avatarUrl: https://avatars.githubusercontent.com/u/653031?u=0c8d8f33d87f1aa1a6488d3f02105e9abc838105&v=4
@ -53,18 +57,18 @@ experts:
count: 46
avatarUrl: https://avatars.githubusercontent.com/u/16958893?u=f8be7088d5076d963984a21f95f44e559192d912&v=4
url: https://github.com/insomnes
- login: jgould22
count: 45
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
url: https://github.com/jgould22
- login: Dustyposa
count: 43
avatarUrl: https://avatars.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4
url: https://github.com/Dustyposa
- login: adriangb
count: 40
avatarUrl: https://avatars.githubusercontent.com/u/1755071?u=81f0262df34e1460ca546fbd0c211169c2478532&v=4
avatarUrl: https://avatars.githubusercontent.com/u/1755071?u=75087f0cf0e9f725f3cd18a899218b6c63ae60d3&v=4
url: https://github.com/adriangb
- login: jgould22
count: 40
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
url: https://github.com/jgould22
- login: includeamin
count: 39
avatarUrl: https://avatars.githubusercontent.com/u/11836741?u=8bd5ef7e62fe6a82055e33c4c0e0a7879ff8cfb6&v=4
@ -73,6 +77,10 @@ experts:
count: 37
avatarUrl: https://avatars.githubusercontent.com/u/5167622?u=de8f597c81d6336fcebc37b32dfd61a3f877160c&v=4
url: https://github.com/STeveShary
- login: chbndrhnns
count: 35
avatarUrl: https://avatars.githubusercontent.com/u/7534547?v=4
url: https://github.com/chbndrhnns
- login: prostomarkeloff
count: 33
avatarUrl: https://avatars.githubusercontent.com/u/28061158?u=72309cc1f2e04e40fa38b29969cb4e9d3f722e7b&v=4
@ -85,20 +93,16 @@ experts:
count: 31
avatarUrl: https://avatars.githubusercontent.com/u/31960541?u=47f4829c77f4962ab437ffb7995951e41eeebe9b&v=4
url: https://github.com/krishnardt
- login: chbndrhnns
count: 30
avatarUrl: https://avatars.githubusercontent.com/u/7534547?v=4
url: https://github.com/chbndrhnns
- login: wshayes
count: 29
avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
url: https://github.com/wshayes
- login: panla
count: 27
count: 29
avatarUrl: https://avatars.githubusercontent.com/u/41326348?u=ba2fda6b30110411ecbf406d187907e2b420ac19&v=4
url: https://github.com/panla
- login: acidjunk
count: 25
count: 27
avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
url: https://github.com/acidjunk
- login: ghandic
@ -125,14 +129,14 @@ experts:
count: 21
avatarUrl: https://avatars.githubusercontent.com/u/565544?v=4
url: https://github.com/chris-allnutt
- login: odiseo0
count: 21
avatarUrl: https://avatars.githubusercontent.com/u/87550035?u=ab724eae71c3fe1cf81e8dc76e73415da926ef7d&v=4
url: https://github.com/odiseo0
- login: retnikt
count: 19
avatarUrl: https://avatars.githubusercontent.com/u/24581770?v=4
url: https://github.com/retnikt
- login: odiseo0
count: 19
avatarUrl: https://avatars.githubusercontent.com/u/87550035?u=ab724eae71c3fe1cf81e8dc76e73415da926ef7d&v=4
url: https://github.com/odiseo0
- login: Hultner
count: 18
avatarUrl: https://avatars.githubusercontent.com/u/2669034?u=115e53df959309898ad8dc9443fbb35fee71df07&v=4
@ -171,8 +175,12 @@ experts:
url: https://github.com/hellocoldworld
- login: haizaar
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/58201?u=4f1f9843d69433ca0d380d95146cfe119e5fdac4&v=4
avatarUrl: https://avatars.githubusercontent.com/u/58201?u=dd40d99a3e1935d0b768f122bfe2258d6ea53b2b&v=4
url: https://github.com/haizaar
- login: yinziyan1206
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/37829370?v=4
url: https://github.com/yinziyan1206
- login: valentin994
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/42819267?u=fdeeaa9242a59b243f8603496b00994f6951d5a2&v=4
@ -181,47 +189,39 @@ experts:
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/17401854?u=474680c02b94cba810cb9032fb7eb787d9cc9d22&v=4
url: https://github.com/David-Lor
- login: yinziyan1206
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/37829370?v=4
url: https://github.com/yinziyan1206
- login: n8sty
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/2964996?v=4
url: https://github.com/n8sty
- login: lowercase00
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/21188280?v=4
url: https://github.com/lowercase00
- login: zamiramir
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/40475662?u=e58ef61034e8d0d6a312cc956fb09b9c3332b449&v=4
url: https://github.com/zamiramir
- login: zoliknemet
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/22326718?u=31ba446ac290e23e56eea8e4f0c558aaf0b40779&v=4
url: https://github.com/zoliknemet
last_month_active:
- login: JarroVGIT
count: 30
count: 27
avatarUrl: https://avatars.githubusercontent.com/u/13659033?u=e8bea32d07a5ef72f7dde3b2079ceb714923ca05&v=4
url: https://github.com/JarroVGIT
- login: zoliknemet
count: 9
avatarUrl: https://avatars.githubusercontent.com/u/22326718?u=31ba446ac290e23e56eea8e4f0c558aaf0b40779&v=4
url: https://github.com/zoliknemet
- login: iudeen
count: 5
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4
url: https://github.com/iudeen
- login: mbroton
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/50829834?u=a48610bf1bffaa9c75d03228926e2eb08a2e24ee&v=4
url: https://github.com/mbroton
- login: csrgxtu
count: 6
avatarUrl: https://avatars.githubusercontent.com/u/5053620?u=9655a3e9661492fcdaaf99193eb16d5cbcc3849e&v=4
url: https://github.com/csrgxtu
- login: Kludex
count: 5
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex
- login: odiseo0
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/87550035?u=ab724eae71c3fe1cf81e8dc76e73415da926ef7d&v=4
url: https://github.com/odiseo0
- login: jonatasoli
- login: jgould22
count: 3
avatarUrl: https://avatars.githubusercontent.com/u/26334101?u=071c062d2861d3dd127f6b4a5258cd8ef55d4c50&v=4
url: https://github.com/jonatasoli
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
url: https://github.com/jgould22
top_contributors:
- login: waynerv
count: 25
@ -236,9 +236,13 @@ top_contributors:
avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=58ed2a45798a4339700e2f62b2e12e6e54bf0396&v=4
url: https://github.com/dmontagu
- login: jaystone776
count: 15
count: 16
avatarUrl: https://avatars.githubusercontent.com/u/11191137?u=299205a95e9b6817a43144a48b643346a5aac5cc&v=4
url: https://github.com/jaystone776
- login: Kludex
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex
- login: euri10
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/1104190?u=321a2e953e6645a7d09b732786c7a8061e0f8a8b&v=4
@ -247,14 +251,14 @@ top_contributors:
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/11489395?u=4adb6986bf3debfc2b8216ae701f2bd47d73da7d&v=4
url: https://github.com/mariacamilagl
- login: Kludex
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex
- login: Smlep
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/16785985?v=4
url: https://github.com/Smlep
- login: dependabot
count: 9
avatarUrl: https://avatars.githubusercontent.com/in/29110?v=4
url: https://github.com/apps/dependabot
- login: Serrones
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/22691749?u=4795b880e13ca33a73e52fc0ef7dc9c60c8fce47&v=4
@ -279,10 +283,10 @@ top_contributors:
count: 5
avatarUrl: https://avatars.githubusercontent.com/u/1175560?v=4
url: https://github.com/Attsun1031
- login: dependabot
- login: ComicShrimp
count: 5
avatarUrl: https://avatars.githubusercontent.com/in/29110?v=4
url: https://github.com/apps/dependabot
avatarUrl: https://avatars.githubusercontent.com/u/43503750?u=b3e4d9a14d9a65d429ce62c566aef73178b7111d&v=4
url: https://github.com/ComicShrimp
- login: jekirl
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/2546697?u=a027452387d85bd4a14834e19d716c99255fb3b7&v=4
@ -293,7 +297,7 @@ top_contributors:
url: https://github.com/jfunez
- login: ycd
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=826f228edf0bab0d19ad1d5c4ba4df1047ccffef&v=4
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=fa40e037060d62bf82e16b505d870a2866725f38&v=4
url: https://github.com/ycd
- login: komtaki
count: 4
@ -303,25 +307,33 @@ top_contributors:
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/3360631?u=5fa1f475ad784d64eb9666bdd43cc4d285dcc773&v=4
url: https://github.com/hitrust
- login: rjNemo
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/56785022?u=d5c3a02567c8649e146fcfc51b6060ccaf8adef8&v=4
url: https://github.com/rjNemo
- login: lsglucas
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/61513630?u=320e43fe4dc7bc6efc64e9b8f325f8075634fd20&v=4
url: https://github.com/lsglucas
- login: ComicShrimp
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/43503750?u=b3e4d9a14d9a65d429ce62c566aef73178b7111d&v=4
url: https://github.com/ComicShrimp
- login: NinaHwang
count: 4
avatarUrl: https://avatars.githubusercontent.com/u/79563565?u=1741703bd6c8f491503354b363a86e879b4c1cab&v=4
url: https://github.com/NinaHwang
- login: pre-commit-ci
count: 4
avatarUrl: https://avatars.githubusercontent.com/in/68672?v=4
url: https://github.com/apps/pre-commit-ci
top_reviewers:
- login: Kludex
count: 95
count: 101
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
url: https://github.com/Kludex
- login: BilalAlpaslan
count: 64
avatarUrl: https://avatars.githubusercontent.com/u/47563997?u=63ed66e304fe8d765762c70587d61d9196e5c82d&v=4
url: https://github.com/BilalAlpaslan
- login: tokusumi
count: 49
count: 50
avatarUrl: https://avatars.githubusercontent.com/u/41147016?u=55010621aece725aa702270b54fed829b6a1fe60&v=4
url: https://github.com/tokusumi
- login: waynerv
@ -332,22 +344,18 @@ top_reviewers:
count: 47
avatarUrl: https://avatars.githubusercontent.com/u/59285379?v=4
url: https://github.com/Laineyzhang55
- login: BilalAlpaslan
count: 45
avatarUrl: https://avatars.githubusercontent.com/u/47563997?u=63ed66e304fe8d765762c70587d61d9196e5c82d&v=4
url: https://github.com/BilalAlpaslan
- login: yezz123
count: 46
avatarUrl: https://avatars.githubusercontent.com/u/52716203?u=636b4f79645176df4527dd45c12d5dbb5a4193cf&v=4
url: https://github.com/yezz123
- login: ycd
count: 45
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=826f228edf0bab0d19ad1d5c4ba4df1047ccffef&v=4
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=fa40e037060d62bf82e16b505d870a2866725f38&v=4
url: https://github.com/ycd
- login: cikay
count: 41
avatarUrl: https://avatars.githubusercontent.com/u/24587499?u=e772190a051ab0eaa9c8542fcff1892471638f2b&v=4
url: https://github.com/cikay
- login: yezz123
count: 34
avatarUrl: https://avatars.githubusercontent.com/u/52716203?u=636b4f79645176df4527dd45c12d5dbb5a4193cf&v=4
url: https://github.com/yezz123
- login: AdrianDeAnda
count: 33
avatarUrl: https://avatars.githubusercontent.com/u/1024932?u=b2ea249c6b41ddf98679c8d110d0f67d4a3ebf93&v=4
@ -356,10 +364,18 @@ top_reviewers:
count: 31
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=b0f2c37142f4b762e41ad65dc49581813422bd71&v=4
url: https://github.com/ArcLightSlavik
- login: JarroVGIT
count: 31
avatarUrl: https://avatars.githubusercontent.com/u/13659033?u=e8bea32d07a5ef72f7dde3b2079ceb714923ca05&v=4
url: https://github.com/JarroVGIT
- login: cassiobotaro
count: 25
avatarUrl: https://avatars.githubusercontent.com/u/3127847?u=b0a652331da17efeb85cd6e3a4969182e5004804&v=4
url: https://github.com/cassiobotaro
- login: lsglucas
count: 24
avatarUrl: https://avatars.githubusercontent.com/u/61513630?u=320e43fe4dc7bc6efc64e9b8f325f8075634fd20&v=4
url: https://github.com/lsglucas
- login: dmontagu
count: 23
avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=58ed2a45798a4339700e2f62b2e12e6e54bf0396&v=4
@ -369,21 +385,13 @@ top_reviewers:
avatarUrl: https://avatars.githubusercontent.com/u/39375566?u=260ad6b1a4b34c07dbfa728da5e586f16f6d1824&v=4
url: https://github.com/komtaki
- login: hard-coders
count: 19
count: 20
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
url: https://github.com/hard-coders
- login: 0417taehyun
count: 19
avatarUrl: https://avatars.githubusercontent.com/u/63915557?u=47debaa860fd52c9b98c97ef357ddcec3b3fb399&v=4
url: https://github.com/0417taehyun
- login: lsglucas
count: 18
avatarUrl: https://avatars.githubusercontent.com/u/61513630?u=320e43fe4dc7bc6efc64e9b8f325f8075634fd20&v=4
url: https://github.com/lsglucas
- login: JarroVGIT
count: 18
avatarUrl: https://avatars.githubusercontent.com/u/13659033?u=e8bea32d07a5ef72f7dde3b2079ceb714923ca05&v=4
url: https://github.com/JarroVGIT
- login: zy7y
count: 17
avatarUrl: https://avatars.githubusercontent.com/u/67154681?u=5d634834cc514028ea3f9115f7030b99a1f4d5a4&v=4
@ -416,6 +424,10 @@ top_reviewers:
count: 15
avatarUrl: https://avatars.githubusercontent.com/u/63476957?u=6c86e59b48e0394d4db230f37fc9ad4d7e2c27c7&v=4
url: https://github.com/delhi09
- login: iudeen
count: 14
avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4
url: https://github.com/iudeen
- login: sh0nk
count: 13
avatarUrl: https://avatars.githubusercontent.com/u/6478810?u=af15d724875cec682ed8088a86d36b2798f981c0&v=4
@ -424,6 +436,14 @@ top_reviewers:
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/31848542?u=efb5b45b55584450507834f279ce48d4d64dea2f&v=4
url: https://github.com/RunningIkkyu
- login: odiseo0
count: 12
avatarUrl: https://avatars.githubusercontent.com/u/87550035?u=ab724eae71c3fe1cf81e8dc76e73415da926ef7d&v=4
url: https://github.com/odiseo0
- login: LorhanSohaky
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/16273730?u=095b66f243a2cd6a0aadba9a095009f8aaf18393&v=4
url: https://github.com/LorhanSohaky
- login: solomein-sv
count: 11
avatarUrl: https://avatars.githubusercontent.com/u/46193920?u=46acfb4aeefb1d7b9fdc5a8cbd9eb8744683c47a&v=4
@ -440,13 +460,13 @@ top_reviewers:
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/7887703?v=4
url: https://github.com/maoyibo
- login: odiseo0
- login: ComicShrimp
count: 10
avatarUrl: https://avatars.githubusercontent.com/u/87550035?u=ab724eae71c3fe1cf81e8dc76e73415da926ef7d&v=4
url: https://github.com/odiseo0
avatarUrl: https://avatars.githubusercontent.com/u/43503750?u=b3e4d9a14d9a65d429ce62c566aef73178b7111d&v=4
url: https://github.com/ComicShrimp
- login: graingert
count: 9
avatarUrl: https://avatars.githubusercontent.com/u/413772?v=4
avatarUrl: https://avatars.githubusercontent.com/u/413772?u=64b77b6aa405c68a9c6bcf45f84257c66eea5f32&v=4
url: https://github.com/graingert
- login: PandaHun
count: 9
@ -460,6 +480,10 @@ top_reviewers:
count: 9
avatarUrl: https://avatars.githubusercontent.com/u/69092910?u=4ac58eab99bd37d663f3d23551df96d4fbdbf760&v=4
url: https://github.com/bezaca
- login: izaguerreiro
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/2241504?v=4
url: https://github.com/izaguerreiro
- login: raphaelauv
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
@ -472,10 +496,6 @@ top_reviewers:
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/5690226?v=4
url: https://github.com/rogerbrinkmann
- login: ComicShrimp
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/43503750?u=b3e4d9a14d9a65d429ce62c566aef73178b7111d&v=4
url: https://github.com/ComicShrimp
- login: NinaHwang
count: 8
avatarUrl: https://avatars.githubusercontent.com/u/79563565?u=1741703bd6c8f491503354b363a86e879b4c1cab&v=4
@ -488,6 +508,10 @@ top_reviewers:
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/22691749?u=4795b880e13ca33a73e52fc0ef7dc9c60c8fce47&v=4
url: https://github.com/Serrones
- login: jovicon
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/21287303?u=b049eac3e51a4c0473c2efe66b4d28a7d8f2b572&v=4
url: https://github.com/jovicon
- login: ryuckel
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/36391432?u=094eec0cfddd5013f76f31e55e56147d78b19553&v=4
@ -496,19 +520,3 @@ top_reviewers:
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/8245071?u=b3afd005f9e4bf080c219ef61a592b3a8004b764&v=4
url: https://github.com/NastasiaSaby
- login: Mause
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/1405026?v=4
url: https://github.com/Mause
- login: wakabame
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/35513518?v=4
url: https://github.com/wakabame
- login: AlexandreBiguet
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/1483079?u=ff926455cd4cab03c6c49441aa5dc2b21df3e266&v=4
url: https://github.com/AlexandreBiguet
- login: krocdort
count: 7
avatarUrl: https://avatars.githubusercontent.com/u/34248814?v=4
url: https://github.com/krocdort

2
docs/en/docs/advanced/dataclasses.md

@ -8,7 +8,7 @@ But FastAPI also supports using <a href="https://docs.python.org/3/library/datac
{!../../../docs_src/dataclasses/tutorial001.py!}
```
This is still thanks to **Pydantic**, as it has <a href="https://pydantic-docs.helpmanual.io/usage/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">internal support for `dataclasses`</a>.
This is still supported thanks to **Pydantic**, as it has <a href="https://pydantic-docs.helpmanual.io/usage/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">internal support for `dataclasses`</a>.
So, even with the code above that doesn't use Pydantic explicitly, FastAPI is using Pydantic to convert those standard dataclasses to Pydantic's own flavor of dataclasses.

44
docs/en/docs/contributing.md

@ -99,61 +99,29 @@ $ python -m pip install --upgrade pip
!!! tip
Every time you install a new package with `pip` under that environment, activate the environment again.
This makes sure that if you use a terminal program installed by that package (like `flit`), you use the one from your local environment and not any other that could be installed globally.
This makes sure that if you use a terminal program installed by that package, you use the one from your local environment and not any other that could be installed globally.
### Flit
### pip
**FastAPI** uses <a href="https://flit.readthedocs.io/en/latest/index.html" class="external-link" target="_blank">Flit</a> to build, package and publish the project.
After activating the environment as described above, install `flit`:
After activating the environment as described above:
<div class="termy">
```console
$ pip install flit
$ pip install -e .[dev,doc,test]
---> 100%
```
</div>
Now re-activate the environment to make sure you are using the `flit` you just installed (and not a global one).
And now use `flit` to install the development dependencies:
=== "Linux, macOS"
<div class="termy">
```console
$ flit install --deps develop --symlink
---> 100%
```
</div>
=== "Windows"
If you are on Windows, use `--pth-file` instead of `--symlink`:
<div class="termy">
```console
$ flit install --deps develop --pth-file
---> 100%
```
</div>
It will install all the dependencies and your local FastAPI in your local environment.
#### Using your local FastAPI
If you create a Python file that imports and uses FastAPI, and run it with the Python from your local environment, it will use your local FastAPI source code.
And if you update that local FastAPI source code, as it is installed with `--symlink` (or `--pth-file` on Windows), when you run that Python file again, it will use the fresh version of FastAPI you just edited.
And if you update that local FastAPI source code, as it is installed with `-e`, when you run that Python file again, it will use the fresh version of FastAPI you just edited.
That way, you don't have to "install" your local version to be able to test every change.
@ -171,7 +139,7 @@ $ bash scripts/format.sh
It will also auto-sort all your imports.
For it to sort them correctly, you need to have FastAPI installed locally in your environment, with the command in the section above using `--symlink` (or `--pth-file` on Windows).
For it to sort them correctly, you need to have FastAPI installed locally in your environment, with the command in the section above using `-e`.
## Docs

8
docs/en/docs/index.md

@ -27,7 +27,7 @@
---
FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.6+ based on standard Python type hints.
FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.7+ based on standard Python type hints.
The key features are:
@ -109,7 +109,7 @@ If you are building a <abbr title="Command Line Interface">CLI</abbr> app to be
## Requirements
Python 3.6+
Python 3.7+
FastAPI stands on the shoulders of giants:
@ -128,7 +128,7 @@ $ pip install fastapi
</div>
You will also need an ASGI server, for production such as <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> or <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>.
You will also need an ASGI server, for production such as <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> or <a href="https://github.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>.
<div class="termy">
@ -325,7 +325,7 @@ 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+**.
Just standard **Python 3.7+**.
For example, for an `int`:

113
docs/en/docs/release-notes.md

@ -2,15 +2,120 @@
## Latest Changes
* 🐛 Make sure a parameter defined as required is kept required in OpenAPI even if defined as optional in another dependency. PR [#4319](https://github.com/tiangolo/fastapi/pull/4319) by [@cd17822](https://github.com/cd17822).
* ♻ Internal small refactor, move `operation_id` parameter position in delete method for consistency with the code. PR [#4474](https://github.com/tiangolo/fastapi/pull/4474) by [@hiel](https://github.com/hiel).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#5408](https://github.com/tiangolo/fastapi/pull/5408) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ⬆️ Upgrade Typer to include Rich in scripts for docs. PR [#5502](https://github.com/tiangolo/fastapi/pull/5502) by [@tiangolo](https://github.com/tiangolo).
* 🐛 Fix calling `mkdocs` for languages as a subprocess to fix/enable MkDocs Material search plugin. PR [#5501](https://github.com/tiangolo/fastapi/pull/5501) by [@tiangolo](https://github.com/tiangolo).
## 0.85.1
### Fixes
* 🐛 Fix support for strings in OpenAPI status codes: `default`, `1XX`, `2XX`, `3XX`, `4XX`, `5XX`. PR [#5187](https://github.com/tiangolo/fastapi/pull/5187) by [@JarroVGIT](https://github.com/JarroVGIT).
### Docs
* 📝 Add WayScript x FastAPI Tutorial to External Links section. PR [#5407](https://github.com/tiangolo/fastapi/pull/5407) by [@moneeka](https://github.com/moneeka).
### Internal
* 👥 Update FastAPI People. PR [#5447](https://github.com/tiangolo/fastapi/pull/5447) by [@github-actions[bot]](https://github.com/apps/github-actions).
* 🔧 Disable Material for MkDocs search plugin. PR [#5495](https://github.com/tiangolo/fastapi/pull/5495) by [@tiangolo](https://github.com/tiangolo).
* 🔇 Ignore Trio warning in tests for CI. PR [#5483](https://github.com/tiangolo/fastapi/pull/5483) by [@samuelcolvin](https://github.com/samuelcolvin).
## 0.85.0
### Features
* ⬆ Upgrade version required of Starlette from `0.19.1` to `0.20.4`. Initial PR [#4820](https://github.com/tiangolo/fastapi/pull/4820) by [@Kludex](https://github.com/Kludex).
* This includes several bug fixes in Starlette.
* ⬆️ Upgrade Uvicorn max version in public extras: all. From `>=0.12.0,<0.18.0` to `>=0.12.0,<0.19.0`. PR [#5401](https://github.com/tiangolo/fastapi/pull/5401) by [@tiangolo](https://github.com/tiangolo).
### Internal
* ⬆️ Upgrade dependencies for doc and dev internal extras: Typer, Uvicorn. PR [#5400](https://github.com/tiangolo/fastapi/pull/5400) by [@tiangolo](https://github.com/tiangolo).
* ⬆️ Upgrade test dependencies: Black, HTTPX, databases, types-ujson. PR [#5399](https://github.com/tiangolo/fastapi/pull/5399) by [@tiangolo](https://github.com/tiangolo).
* ⬆️ Upgrade mypy and tweak internal type annotations. PR [#5398](https://github.com/tiangolo/fastapi/pull/5398) by [@tiangolo](https://github.com/tiangolo).
* 🔧 Update test dependencies, upgrade Pytest, move dependencies from dev to test. PR [#5396](https://github.com/tiangolo/fastapi/pull/5396) by [@tiangolo](https://github.com/tiangolo).
## 0.84.0
### Breaking Changes
This version of FastAPI drops support for Python 3.6. 🔥 Please upgrade to a supported version of Python (3.7 or above), Python 3.6 reached the end-of-life a long time ago. 😅☠
* 🔧 Update package metadata, drop support for Python 3.6, move build internals from Flit to Hatch. PR [#5240](https://github.com/tiangolo/fastapi/pull/5240) by [@ofek](https://github.com/ofek).
## 0.83.0
🚨 This is probably the last release (or one of the last releases) to support Python 3.6. 🔥
Python 3.6 reached the [end-of-life and is no longer supported by Python](https://www.python.org/downloads/release/python-3615/) since around a year ago.
You hopefully updated to a supported version of Python a while ago. If you haven't, you really should.
### Features
* ✨ Add support in `jsonable_encoder` for include and exclude with dataclasses. PR [#4923](https://github.com/tiangolo/fastapi/pull/4923) by [@DCsunset](https://github.com/DCsunset).
### Fixes
* 🐛 Fix `RuntimeError` raised when `HTTPException` has a status code with no content. PR [#5365](https://github.com/tiangolo/fastapi/pull/5365) by [@iudeen](https://github.com/iudeen).
* 🐛 Fix empty reponse body when default `status_code` is empty but the a `Response` parameter with `response.status_code` is set. PR [#5360](https://github.com/tiangolo/fastapi/pull/5360) by [@tmeckel](https://github.com/tmeckel).
### Docs
* 📝 Update `SECURITY.md`. PR [#5377](https://github.com/tiangolo/fastapi/pull/5377) by [@Kludex](https://github.com/Kludex).
### Internal
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#5352](https://github.com/tiangolo/fastapi/pull/5352) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
## 0.82.0
🚨 This is probably the last release (or one of the last releases) to support Python 3.6. 🔥
Python 3.6 reached the [end-of-life and is no longer supported by Python](https://www.python.org/downloads/release/python-3615/) since around a year ago.
You hopefully updated to a supported version of Python a while ago. If you haven't, you really should.
### Features
* ✨ Export `WebSocketState` in `fastapi.websockets`. PR [#4376](https://github.com/tiangolo/fastapi/pull/4376) by [@matiuszka](https://github.com/matiuszka).
* ✨ Support Python internal description on Pydantic model's docstring. PR [#3032](https://github.com/tiangolo/fastapi/pull/3032) by [@Kludex](https://github.com/Kludex).
* ✨ Update `ORJSONResponse` to support non `str` keys and serializing Numpy arrays. PR [#3892](https://github.com/tiangolo/fastapi/pull/3892) by [@baby5](https://github.com/baby5).
* 🔧 Update sponsors, disable ImgWhale. PR [#5338](https://github.com/tiangolo/fastapi/pull/5338) by [@tiangolo](https://github.com/tiangolo).
### Fixes
* 🐛 Allow exit code for dependencies with `yield` to always execute, by removing capacity limiter for them, to e.g. allow closing DB connections without deadlocks. PR [#5122](https://github.com/tiangolo/fastapi/pull/5122) by [@adriangb](https://github.com/adriangb).
* 🐛 Fix FastAPI People GitHub Action: set HTTPX timeout for GraphQL query request. PR [#5222](https://github.com/tiangolo/fastapi/pull/5222) by [@iudeen](https://github.com/iudeen).
* 🐛 Make sure a parameter defined as required is kept required in OpenAPI even if defined as optional in another dependency. PR [#4319](https://github.com/tiangolo/fastapi/pull/4319) by [@cd17822](https://github.com/cd17822).
* 🐛 Fix support for path parameters in WebSockets. PR [#3879](https://github.com/tiangolo/fastapi/pull/3879) by [@davidbrochart](https://github.com/davidbrochart).
### Docs
* ✏ Update Hypercorn link, now pointing to GitHub. PR [#5346](https://github.com/tiangolo/fastapi/pull/5346) by [@baconfield](https://github.com/baconfield).
* ✏ Tweak wording in `docs/en/docs/advanced/dataclasses.md`. PR [#3698](https://github.com/tiangolo/fastapi/pull/3698) by [@pfackeldey](https://github.com/pfackeldey).
* 📝 Add note about Python 3.10 `X | Y` operator in explanation about Response Models. PR [#5307](https://github.com/tiangolo/fastapi/pull/5307) by [@MendyLanda](https://github.com/MendyLanda).
* 📝 Add link to New Relic article: "How to monitor FastAPI application performance using Python agent". PR [#5260](https://github.com/tiangolo/fastapi/pull/5260) by [@sjyothi54](https://github.com/sjyothi54).
* 📝 Update docs for `ORJSONResponse` with details about improving performance. PR [#2615](https://github.com/tiangolo/fastapi/pull/2615) by [@falkben](https://github.com/falkben).
* 📝 Add docs for creating a custom Response class. PR [#5331](https://github.com/tiangolo/fastapi/pull/5331) by [@tiangolo](https://github.com/tiangolo).
* 📝 Add tip about using alias for form data fields. PR [#5329](https://github.com/tiangolo/fastapi/pull/5329) by [@tiangolo](https://github.com/tiangolo).
* 🐛 Fix support for path parameters in WebSockets. PR [#3879](https://github.com/tiangolo/fastapi/pull/3879) by [@davidbrochart](https://github.com/davidbrochart).
### Translations
* 🌐 Add Russian translation for `docs/ru/docs/features.md`. PR [#5315](https://github.com/tiangolo/fastapi/pull/5315) by [@Xewus](https://github.com/Xewus).
* 🌐 Update Chinese translation for `docs/zh/docs/tutorial/request-files.md`. PR [#4529](https://github.com/tiangolo/fastapi/pull/4529) by [@ASpathfinder](https://github.com/ASpathfinder).
* 🌐 Add Chinese translation for `docs/zh/docs/tutorial/encoder.md`. PR [#4969](https://github.com/tiangolo/fastapi/pull/4969) by [@Zssaer](https://github.com/Zssaer).
* 🌐 Fix MkDocs file line for Portuguese translation of `background-task.md`. PR [#5242](https://github.com/tiangolo/fastapi/pull/5242) by [@ComicShrimp](https://github.com/ComicShrimp).
### Internal
* 👥 Update FastAPI People. PR [#5347](https://github.com/tiangolo/fastapi/pull/5347) by [@github-actions[bot]](https://github.com/apps/github-actions).
* ⬆ Bump dawidd6/action-download-artifact from 2.22.0 to 2.23.0. PR [#5321](https://github.com/tiangolo/fastapi/pull/5321) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ [pre-commit.ci] pre-commit autoupdate. PR [#5318](https://github.com/tiangolo/fastapi/pull/5318) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
* ✏ Fix a small code highlight line error. PR [#5256](https://github.com/tiangolo/fastapi/pull/5256) by [@hjlarry](https://github.com/hjlarry).
* ♻ Internal small refactor, move `operation_id` parameter position in delete method for consistency with the code. PR [#4474](https://github.com/tiangolo/fastapi/pull/4474) by [@hiel](https://github.com/hiel).
* 🔧 Update sponsors, disable ImgWhale. PR [#5338](https://github.com/tiangolo/fastapi/pull/5338) by [@tiangolo](https://github.com/tiangolo).
## 0.81.0

2
docs/en/docs/tutorial/query-params-str-validations.md

@ -216,7 +216,7 @@ To do that, you can declare that `None` is a valid type but still use `default=.
=== "Python 3.6 and above"
```Python hl_lines="8"
```Python hl_lines="9"
{!> ../../../docs_src/query_params_str_validations/tutorial006c.py!}
```

2
docs/en/docs/tutorial/response-model.md

@ -168,7 +168,7 @@ Your response model could have default values, like:
{!> ../../../docs_src/response_model/tutorial004_py310.py!}
```
* `description: Union[str, None] = None` has a default of `None`.
* `description: Union[str, None] = None` (or `str | None = None` in Python 3.10) has a default of `None`.
* `tax: float = 10.5` has a default of `10.5`.
* `tags: List[str] = []` as a default of an empty list: `[]`.

2
docs/es/docs/index.md

@ -106,7 +106,7 @@ Si estás construyendo un app de <abbr title="Interfaz de línea de comandos en
## Requisitos
Python 3.6+
Python 3.7+
FastAPI está sobre los hombros de gigantes:

2
docs/fr/docs/index.md

@ -111,7 +111,7 @@ If you are building a <abbr title="Command Line Interface">CLI</abbr> app to be
## Requirements
Python 3.6+
Python 3.7+
FastAPI stands on the shoulders of giants:

2
docs/id/docs/index.md

@ -111,7 +111,7 @@ If you are building a <abbr title="Command Line Interface">CLI</abbr> app to be
## Requirements
Python 3.6+
Python 3.7+
FastAPI stands on the shoulders of giants:

2
docs/it/docs/index.md

@ -111,7 +111,7 @@ If you are building a <abbr title="Command Line Interface">CLI</abbr> app to be
## Requirements
Python 3.6+
Python 3.7+
FastAPI stands on the shoulders of giants:

45
docs/ja/docs/contributing.md

@ -88,62 +88,29 @@ $ python -m venv env
!!! tip "豆知識"
この環境で`pip`を使って新しいパッケージをインストールするたびに、仮想環境を再度有効化します。
これにより、そのパッケージによってインストールされたターミナルのプログラム (`flit`など) を使用する場合、ローカル環境のものを使用し、グローバルにインストールされたものは使用されなくなります。
これにより、そのパッケージによってインストールされたターミナルのプログラム を使用する場合、ローカル環境のものを使用し、グローバルにインストールされたものは使用されなくなります。
### Flit
### pip
**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
$ pip install -e .[dev,doc,test]
---> 100%
```
</div>
次に、環境を再び有効化して、インストールしたばかりの`flit` (グローバルではない) を使用していることを確認します。
そして、`flit`を使用して開発のための依存関係をインストールします:
=== "Linux, macOS"
<div class="termy">
```console
$ flit install --deps develop --symlink
---> 100%
```
</div>
=== "Windows"
Windowsユーザーは、`--symlink`のかわりに`--pth-file`を使用します:
<div class="termy">
```console
$ flit install --deps develop --pth-file
---> 100%
```
</div>
これで、すべての依存関係とFastAPIを、ローカル環境にインストールします。
#### ローカル環境でFastAPIを使う
FastAPIをインポートして使用するPythonファイルを作成し、ローカル環境で実行すると、ローカルのFastAPIソースコードが使用されます。
そして、`--symlink` (Windowsでは` --pth-file`) でインストールされているローカルのFastAPIソースコードを更新した場合、そのPythonファイルを再度実行すると、更新したばかりの新しいバージョンのFastAPIが使用されます。
そして、`-e` でインストールされているローカルのFastAPIソースコードを更新した場合、そのPythonファイルを再度実行すると、更新したばかりの新しいバージョンのFastAPIが使用されます。
これにより、ローカルバージョンを「インストール」しなくても、すべての変更をテストできます。
@ -161,7 +128,7 @@ $ bash scripts/format.sh
また、すべてのインポートを自動でソートします。
正しく並べ替えるには、上記セクションのコマンドで `--symlink` (Windowsの場合は` --pth-file`) を使い、FastAPIをローカル環境にインストールしている必要があります。
正しく並べ替えるには、上記セクションのコマンドで `-e` を使い、FastAPIをローカル環境にインストールしている必要があります。
### インポートの整形

2
docs/ja/docs/index.md

@ -107,7 +107,7 @@ FastAPI は、Pythonの標準である型ヒントに基づいてPython 3.6 以
## 必要条件
Python 3.6+
Python 3.7+
FastAPI は巨人の肩の上に立っています。

2
docs/ko/docs/index.md

@ -107,7 +107,7 @@ FastAPI는 현대적이고, 빠르며(고성능), 파이썬 표준 타입 힌트
## 요구사항
Python 3.6+
Python 3.7+
FastAPI는 거인들의 어깨 위에 서 있습니다:

2
docs/nl/docs/index.md

@ -114,7 +114,7 @@ If you are building a <abbr title="Command Line Interface">CLI</abbr> app to be
## Requirements
Python 3.6+
Python 3.7+
FastAPI stands on the shoulders of giants:

2
docs/pl/docs/index.md

@ -106,7 +106,7 @@ Jeżeli tworzysz aplikacje <abbr title="aplikacja z interfejsem konsolowym">CLI<
## Wymagania
Python 3.6+
Python 3.7+
FastAPI oparty jest na:

44
docs/pt/docs/contributing.md

@ -89,61 +89,29 @@ Se ele exibir o binário `pip` em `env/bin/pip` então funcionou. 🎉
!!! tip
Toda vez que você instalar um novo pacote com `pip` nesse ambiente, ative o ambiente novamente.
Isso garante que se você usar um programa instalado por aquele pacote (como `flit`), você utilizará aquele de seu ambiente local e não outro que possa estar instalado globalmente.
Isso garante que se você usar um programa instalado por aquele pacote, você utilizará aquele de seu ambiente local e não outro que possa estar instalado globalmente.
### Flit
### pip
**FastAPI** utiliza <a href="https://flit.readthedocs.io/en/latest/index.html" class="external-link" target="_blank">Flit</a> para construir, empacotar e publicar o projeto.
Após ativar o ambiente como descrito acima, instale o `flit`:
Após ativar o ambiente como descrito acima:
<div class="termy">
```console
$ pip install flit
$ pip install -e .[dev,doc,test]
---> 100%
```
</div>
Ative novamente o ambiente para ter certeza que você esteja utilizando o `flit` que você acabou de instalar (e não um global).
E agora use `flit` para instalar as dependências de desenvolvimento:
=== "Linux, macOS"
<div class="termy">
```console
$ flit install --deps develop --symlink
---> 100%
```
</div>
=== "Windows"
Se você está no Windows, use `--pth-file` ao invés de `--symlink`:
<div class="termy">
```console
$ flit install --deps develop --pth-file
---> 100%
```
</div>
Isso irá instalar todas as dependências e seu FastAPI local em seu ambiente local.
#### Usando seu FastAPI local
Se você cria um arquivo Python que importa e usa FastAPI, e roda com Python de seu ambiente local, ele irá utilizar o código fonte de seu FastAPI local.
E se você atualizar o código fonte do FastAPI local, como ele é instalado com `--symlink` (ou `--pth-file` no Windows), quando você rodar aquele arquivo Python novamente, ele irá utilizar a nova versão do FastAPI que você acabou de editar.
E se você atualizar o código fonte do FastAPI local, como ele é instalado com `-e`, quando você rodar aquele arquivo Python novamente, ele irá utilizar a nova versão do FastAPI que você acabou de editar.
Desse modo, você não tem que "instalar" sua versão local para ser capaz de testar cada mudança.
@ -161,7 +129,7 @@ $ bash scripts/format.sh
Ele irá organizar também todos os seus imports.
Para que ele organize os imports corretamente, você precisa ter o FastAPI instalado localmente em seu ambiente, com o comando na seção acima usando `--symlink` (ou `--pth-file` no Windows).
Para que ele organize os imports corretamente, você precisa ter o FastAPI instalado localmente em seu ambiente, com o comando na seção acima usando `-e`.
### Formato dos imports

2
docs/pt/docs/index.md

@ -100,7 +100,7 @@ Se você estiver construindo uma aplicação <abbr title="Command Line Interface
## Requisitos
Python 3.6+
Python 3.7+
FastAPI está nos ombros de gigantes:

1
docs/pt/mkdocs.yml

@ -74,6 +74,7 @@ nav:
- tutorial/handling-errors.md
- Segurança:
- tutorial/security/index.md
- tutorial/background-tasks.md
- Guia de Usuário Avançado:
- advanced/index.md
- Implantação:

203
docs/ru/docs/features.md

@ -0,0 +1,203 @@
# Основные свойства
## Основные свойства FastAPI
**FastAPI** предлагает вам следующее:
### Использование открытых стандартов
* <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a> для создания API, включая объявления <abbr title="также известных, как HTTP-методы, такие, как: POST, GET, PUT, DELETE">операций</abbr> <abbr title="известные как: эндпоинты, маршруты, 'ручки' и т.п.">пути</abbr>, параметров, тела запроса, безопасности и т.д.
* Автоматическое документирование моделей данных в соответствии с <a href="https://json-schema.org/" class="external-link" target="_blank"><strong>JSON Schema</strong></a> (так как спецификация OpenAPI сама основана на JSON Schema).
* Разработан, придерживаясь этих стандартов, после тщательного их изучения. Эти стандарты изначально включены во фреймфорк, а не являются дополнительной надстройкой.
* Это также позволяет использовать автоматическую **генерацию клиентского кода** на многих языках.
### Автоматически генерируемая документация
Интерактивная документация для API и исследования пользовательских веб-интерфейсов. Поскольку этот фреймворк основан на OpenAPI, существует несколько вариантов документирования, 2 из которых включены по умолчанию.
* <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank"><strong>Swagger UI</strong></a>, с интерактивным взаимодействием, вызывает и тестирует ваш API прямо из браузера.
![Swagger UI interaction](https://fastapi.tiangolo.com/img/index/index-03-swagger-02.png)
* Альтернативная документация API в <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank"><strong>ReDoc</strong></a>.
![ReDoc](https://fastapi.tiangolo.com/img/index/index-06-redoc-02.png)
### Только современный Python
Все эти возможности основаны на стандартных **аннотациях типов Python 3.6** (благодаря Pydantic). Не нужно изучать новый синтаксис. Только лишь стандартный современный Python.
Если вам нужно освежить знания, как использовать аннотации типов в Python (даже если вы не используете FastAPI), выделите 2 минуты и просмотрите краткое руководство: [Введение в аннотации типов Python¶
](python-types.md){.internal-link target=_blank}.
Вы пишете на стандартном Python с аннотациями типов:
```Python
from datetime import date
from pydantic import BaseModel
# Объявляем параметр user_id с типом `str`
# и получаем поддержку редактора внутри функции
def main(user_id: str):
return user_id
# Модель Pydantic
class User(BaseModel):
id: int
name: str
joined: date
```
Это можно использовать так:
```Python
my_user: User = User(id=3, name="John Doe", joined="2018-07-19")
second_user_data = {
"id": 4,
"name": "Mary",
"joined": "2018-11-30",
}
my_second_user: User = User(**second_user_data)
```
!!! Информация
`**second_user_data` означает:
Передать ключи и значения словаря `second_user_data`, в качестве аргументов типа "ключ-значение", это эквивалентно: `User(id=4, name="Mary", joined="2018-11-30")` .
### Поддержка редакторов (IDE)
Весь фреймворк был продуман так, чтобы быть простым и интуитивно понятным в использовании, все решения были проверены на множестве редакторов еще до начала разработки, чтобы обеспечить наилучшие условия при написании кода.
В опросе Python-разработчиков было выяснено, <a href="https://www.jetbrains.com/research/python-developers-survey-2017/#tools-and-features" class="external-link" target="_blank">что наиболее часто используемой функцией редакторов, является "автодополнение"</a>.
Вся структура **FastAPI** основана на удовлетворении этой возможности. Автодополнение работает везде.
Вам редко нужно будет возвращаться к документации.
Вот как ваш редактор может вам помочь:
* в <a href="https://code.visualstudio.com/" class="external-link" target="_blank">Visual Studio Code</a>:
![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png)
* в <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a>:
![editor support](https://fastapi.tiangolo.com/img/pycharm-completion.png)
Вы будете получать автодополнение кода даже там, где вы считали это невозможным раньше.
Как пример, ключ `price` внутри тела JSON (который может быть вложенным), приходящего в запросе.
Больше никаких неправильных имён ключей, метания по документации или прокручивания кода вверх и вниз, в попытках узнать - использовали вы ранее `username` или `user_name`.
### Краткость
FastAPI имеет продуманные значения **по умолчанию** для всего, с произвольными настройками везде. Все параметры могут быть тонко подстроены так, чтобы делать то, что вам нужно и определять необходимый вам API.
Но, по умолчанию, всё это **"и так работает"**.
### Проверка значений
* Проверка значений для большинства (или всех?) **типов данных** Python, включая:
* Объекты JSON (`dict`).
* Массивы JSON (`list`) с установленными типами элементов.
* Строковые (`str`) поля с ограничением минимальной и максимальной длины.
* Числа (`int`, `float`) с минимальными и максимальными значениями и т.п.
* Проверка для более экзотических типов, таких как:
* URL.
* Email.
* UUID.
* ...и другие.
Все проверки обрабатываются хорошо зарекомендовавшим себя и надежным **Pydantic**.
### Безопасность и аутентификация
Встроеные функции безопасности и аутентификации. Без каких-либо компромиссов с базами данных или моделями данных.
Все схемы безопасности, определённые в OpenAPI, включая:
* HTTP Basic.
* **OAuth2** (также с **токенами JWT**). Ознакомьтесь с руководством [OAuth2 с JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank}.
* Ключи API в:
* Заголовках.
* Параметрах запросов.
* Cookies и т.п.
Вдобавок все функции безопасности от Starlette (включая **сессионные cookies**).
Все инструменты и компоненты спроектированы для многократного использования и легко интегрируются с вашими системами, хранилищами данных, реляционными и NoSQL базами данных и т. д.
### Внедрение зависимостей
FastAPI включает в себя чрезвычайно простую в использовании, но чрезвычайно мощную систему <abbr title='известную как: "components", "resources", "services", "providers"'><strong>Внедрения зависимостей</strong></abbr>.
* Даже зависимости могут иметь зависимости, создавая иерархию или **"графы" зависимостей**.
* Всё **автоматически обрабатывается** фреймворком.
* Все зависимости могут запрашивать данные из запросов и **дополнять операции пути** ограничениями и автоматической документацией.
* **Автоматическая проверка** даже для параметров *операций пути*, определенных в зависимостях.
* Поддержка сложных систем аутентификации пользователей, **соединений с базами данных** и т.д.
* **Никаких компромиссов** с базами данных, интерфейсами и т.д. Но легкая интеграция со всеми ними.
### Нет ограничений на "Плагины"
Или, другими словами, нет сложностей с ними, импортируйте и используйте нужный вам код.
Любая интеграция разработана настолько простой в использовании (с зависимостями), что вы можете создать "плагин" для своего приложения в пару строк кода, используя ту же структуру и синтаксис, что и для ваших *операций пути*.
### Проверен
* 100% <abbr title="Количество автоматически проверямого кода">покрытие тестами</abbr>.
* 100% <abbr title="Аннотации типов Python, благодаря которым ваш редактор и другие инструменты могут обеспечить вам лучшую поддержку">аннотирование типов</abbr> в кодовой базе.
* Используется в реально работающих приложениях.
## Основные свойства Starlette
**FastAPI** основан на <a href="https://www.starlette.io/" class="external-link" target="_blank"><strong>Starlette</strong></a> и полностью совместим с ним. Так что, любой дополнительный код Starlette, который у вас есть, будет также работать.
На самом деле, `FastAPI` - это класс, унаследованный от `Starlette`. Таким образом, если вы уже знаете или используете Starlette, большая часть функционала будет работать так же.
С **FastAPI** вы получаете все возможности **Starlette** (так как FastAPI это всего лишь Starlette на стероидах):
* Серьёзно впечатляющая производительность. Это <a href="https://github.com/encode/starlette#performance" class="external-link" target="_blank">один из самых быстрых фреймворков на Python</a>, наравне с приложениями использующими **NodeJS** или **Go**.
* Поддержка **WebSocket**.
* Фоновые задачи для процессов.
* События запуска и выключения.
* Тестовый клиент построен на библиотеке `requests`.
* **CORS**, GZip, статические файлы, потоковые ответы.
* Поддержка **сессий и cookie**.
* 100% покрытие тестами.
* 100% аннотирование типов в кодовой базе.
## Особенности и возможности Pydantic
**FastAPI** основан на <a href="https://pydantic-docs.helpmanual.io" class="external-link" target="_blank"><strong>Pydantic</strong></a> и полностью совместим с ним. Так что, любой дополнительный код Pydantic, который у вас есть, будет также работать.
Включая внешние библиотеки, также основанные на Pydantic, такие как: <abbr title="Object-Relational Mapper">ORM'ы</abbr>, <abbr title="Object-Document Mapper">ODM'ы</abbr> для баз данных.
Это также означает, что во многих случаях вы можете передавать тот же объект, который получили из запроса, **непосредственно в базу данных**, так как всё проверяется автоматически.
И наоборот, во многих случаях вы можете просто передать объект, полученный из базы данных, **непосредственно клиенту**.
С **FastAPI** вы получаете все возможности **Pydantic** (так как, FastAPI основан на Pydantic, для обработки данных):
* **Никакой нервотрёпки** :
* Не нужно изучать новых схем в микроязыках.
* Если вы знаете аннотации типов в Python, вы знаете, как использовать Pydantic.
* Прекрасно сочетается с вашими **<abbr title="Интегрированное окружение для разработки, похожее на текстовый редактор">IDE</abbr>/<abbr title="программа проверяющая ошибки в коде">linter</abbr>/мозгом**:
* Потому что структуры данных pydantic - это всего лишь экземпляры классов, определённых вами. Автодополнение, проверка кода, mypy и ваша интуиция - всё будет работать с вашими проверенными данными.
* **Быстродействие**:
* В <a href="https://pydantic-docs.helpmanual.io/benchmarks/" class="external-link" target="_blank">тестовых замерах</a> Pydantic быстрее, чем все другие проверенные библиотеки.
* Проверка **сложных структур**:
* Использование иерархических моделей Pydantic; `List`, `Dict` и т.п. из модуля `typing` (входит в стандартную библиотеку Python).
* Валидаторы позволяют четко и легко определять, проверять и документировать сложные схемы данных в виде JSON Schema.
* У вас могут быть глубоко **вложенные объекты JSON** и все они будут проверены и аннотированы.
* **Расширяемость**:
* Pydantic позволяет определять пользовательские типы данных или расширять проверку методами модели, с помощью проверочных декораторов.
* 100% покрытие тестами.

2
docs/ru/docs/index.md

@ -109,7 +109,7 @@ FastAPI — это современный, быстрый (высокопрои
## Зависимости
Python 3.6+
Python 3.7+
FastAPI стоит на плечах гигантов:

1
docs/ru/mkdocs.yml

@ -58,6 +58,7 @@ nav:
- tr: /tr/
- uk: /uk/
- zh: /zh/
- features.md
- python-types.md
- Учебник - руководство пользователя:
- tutorial/background-tasks.md

2
docs/sq/docs/index.md

@ -111,7 +111,7 @@ If you are building a <abbr title="Command Line Interface">CLI</abbr> app to be
## Requirements
Python 3.6+
Python 3.7+
FastAPI stands on the shoulders of giants:

2
docs/sv/docs/index.md

@ -114,7 +114,7 @@ If you are building a <abbr title="Command Line Interface">CLI</abbr> app to be
## Requirements
Python 3.6+
Python 3.7+
FastAPI stands on the shoulders of giants:

2
docs/tr/docs/index.md

@ -119,7 +119,7 @@ Eğer API yerine <abbr title="Command Line Interface">komut satırı uygulaması
## Gereksinimler
Python 3.6+
Python 3.7+
FastAPI iki devin omuzları üstünde duruyor:

2
docs/uk/docs/index.md

@ -111,7 +111,7 @@ If you are building a <abbr title="Command Line Interface">CLI</abbr> app to be
## Requirements
Python 3.6+
Python 3.7+
FastAPI stands on the shoulders of giants:

44
docs/zh/docs/contributing.md

@ -88,61 +88,29 @@ $ python -m venv env
!!! tip
每一次你在该环境下使用 `pip` 安装了新软件包时,请再次激活该环境。
这样可以确保你在使用由该软件包安装的终端程序(如 `flit`时使用的是当前虚拟环境中的程序,而不是其他的可能是全局安装的程序。
这样可以确保你在使用由该软件包安装的终端程序时使用的是当前虚拟环境中的程序,而不是其他的可能是全局安装的程序。
### Flit
### pip
**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
$ pip install -e .[dev,doc,test]
---> 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。
并且如果你更改该本地 FastAPI 的源码,由于它是通过 `-e` 安装的,当你再次运行那个 Python 文件,它将使用你刚刚编辑过的最新版本的 FastAPI。
这样,你不必再去重新"安装"你的本地版本即可测试所有更改。
@ -160,7 +128,7 @@ $ bash scripts/format.sh
它还会自动对所有导入代码进行整理。
为了使整理正确进行,你需要在当前环境中安装本地的 FastAPI,即在运行上述段落中的命令时添加 `--symlink`(或 Windows 上的 `--pth-file`
为了使整理正确进行,你需要在当前环境中安装本地的 FastAPI,即在运行上述段落中的命令时添加 `-e`
### 格式化导入

42
docs/zh/docs/tutorial/encoder.md

@ -0,0 +1,42 @@
# JSON 兼容编码器
在某些情况下,您可能需要将数据类型(如Pydantic模型)转换为与JSON兼容的数据类型(如`dict`、`list`等)。
比如,如果您需要将其存储在数据库中。
对于这种要求, **FastAPI**提供了`jsonable_encoder()`函数。
## 使用`jsonable_encoder`
让我们假设你有一个数据库名为`fake_db`,它只能接收与JSON兼容的数据。
例如,它不接收`datetime`这类的对象,因为这些对象与JSON不兼容。
因此,`datetime`对象必须将转换为包含<a href="https://en.wikipedia.org/wiki/ISO_8601" class="external-link" target="_blank">ISO格式化</a>的`str`类型对象。
同样,这个数据库也不会接收Pydantic模型(带有属性的对象),而只接收`dict`。
对此你可以使用`jsonable_encoder`。
它接收一个对象,比如Pydantic模型,并会返回一个JSON兼容的版本:
=== "Python 3.6 and above"
```Python hl_lines="5 22"
{!> ../../../docs_src/encoder/tutorial001.py!}
```
=== "Python 3.10 and above"
```Python hl_lines="4 21"
{!> ../../../docs_src/encoder/tutorial001_py310.py!}
```
在这个例子中,它将Pydantic模型转换为`dict`,并将`datetime`转换为`str`。
调用它的结果后就可以使用Python标准编码中的<a href="https://docs.python.org/3/library/json.html#json.dumps" class="external-link" target="_blank">`json.dumps()`</a>
这个操作不会返回一个包含JSON格式(作为字符串)数据的庞大的`str`。它将返回一个Python标准数据结构(例如`dict`),其值和子值都与JSON兼容。
!!! note
`jsonable_encoder`实际上是FastAPI内部用来转换数据的。但是它在许多其他场景中也很有用。

63
docs/zh/docs/tutorial/request-files.md

@ -44,9 +44,9 @@
不过,很多情况下,`UploadFile` 更好用。
## 含 `UploadFile` `File` 参数
## 含 `UploadFile`文件参数
定义 `File` 参数时使用 `UploadFile`
定义文件参数时使用 `UploadFile`
```Python hl_lines="12"
{!../../../docs_src/request_files/tutorial001.py!}
@ -94,7 +94,7 @@ contents = myfile.file.read()
!!! note "`async` 技术细节"
使用 `async` 方法时,**FastAPI** 在线程池中执行文件方法,并 `awiat` 操作完成。
使用 `async` 方法时,**FastAPI** 在线程池中执行文件方法,并 `await` 操作完成。
!!! note "Starlette 技术细节"
@ -120,6 +120,30 @@ contents = myfile.file.read()
这不是 **FastAPI** 的问题,而是 HTTP 协议的规定。
## 可选文件上传
您可以通过使用标准类型注解并将 None 作为默认值的方式将一个文件参数设为可选:
=== "Python 3.6 及以上版本"
```Python hl_lines="9 17"
{!> ../../../docs_src/request_files/tutorial001_02.py!}
```
=== "Python 3.9 及以上版本"
```Python hl_lines="7 14"
{!> ../../../docs_src/request_files/tutorial001_02_py310.py!}
```
## 带有额外元数据的 `UploadFile`
您也可以将 `File()``UploadFile` 一起使用,例如,设置额外的元数据:
```Python hl_lines="13"
{!../../../docs_src/request_files/tutorial001_03.py!}
```
## 多文件上传
FastAPI 支持同时上传多个文件。
@ -128,19 +152,20 @@ FastAPI 支持同时上传多个文件。
上传多个文件时,要声明含 `bytes``UploadFile` 的列表(`List`):
```Python hl_lines="10 15"
{!../../../docs_src/request_files/tutorial002.py!}
```
=== "Python 3.6 及以上版本"
接收的也是含 `bytes``UploadFile` 的列表(`list`)。
```Python hl_lines="10 15"
{!> ../../../docs_src/request_files/tutorial002.py!}
```
!!! note "笔记"
=== "Python 3.9 及以上版本"
注意,截至 2019 年 4 月 14 日,Swagger UI 不支持在同一个表单字段中上传多个文件。详见 <a href="https://github.com/swagger-api/swagger-ui/issues/4276" class="external-link" target="_blank">#4276</a><a href="https://github.com/swagger-api/swagger-ui/issues/3641" class="external-link" target="_blank">#3641</a>.
```Python hl_lines="8 13"
{!> ../../../docs_src/request_files/tutorial002_py39.py!}
```
不过,**FastAPI** 已通过 OpenAPI 标准与之兼容。
接收的也是含 `bytes``UploadFile` 的列表(`list`)
因此,只要 Swagger UI 或任何其他支持 OpenAPI 的工具支持多文件上传,都将与 **FastAPI** 兼容。
!!! note "技术细节"
@ -148,6 +173,22 @@ FastAPI 支持同时上传多个文件。
`fastapi.responses` 其实与 `starlette.responses` 相同,只是为了方便开发者调用。实际上,大多数 **FastAPI** 的响应都直接从 Starlette 调用。
### 带有额外元数据的多文件上传
和之前的方式一样, 您可以为 `File()` 设置额外参数, 即使是 `UploadFile`:
=== "Python 3.6 及以上版本"
```Python hl_lines="18"
{!> ../../../docs_src/request_files/tutorial003.py!}
```
=== "Python 3.9 及以上版本"
```Python hl_lines="16"
{!> ../../../docs_src/request_files/tutorial003_py39.py!}
```
## 小结
本节介绍了如何用 `File` 把上传文件声明为(表单数据的)输入参数。

1
docs/zh/mkdocs.yml

@ -85,6 +85,7 @@ nav:
- tutorial/request-forms-and-files.md
- tutorial/handling-errors.md
- tutorial/path-operation-configuration.md
- tutorial/encoder.md
- tutorial/body-updates.md
- 依赖项:
- tutorial/dependencies/index.md

2
fastapi/__init__.py

@ -1,6 +1,6 @@
"""FastAPI framework, high performance, easy to learn, fast to code, ready for production"""
__version__ = "0.81.0"
__version__ = "0.85.1"
from starlette import status as status

3
fastapi/applications.py

@ -33,9 +33,10 @@ from fastapi.types import DecoratedCallable
from fastapi.utils import generate_unique_id
from starlette.applications import Starlette
from starlette.datastructures import State
from starlette.exceptions import ExceptionMiddleware, HTTPException
from starlette.exceptions import HTTPException
from starlette.middleware import Middleware
from starlette.middleware.errors import ServerErrorMiddleware
from starlette.middleware.exceptions import ExceptionMiddleware
from starlette.requests import Request
from starlette.responses import HTMLResponse, JSONResponse, Response
from starlette.routing import BaseRoute

30
fastapi/concurrency.py

@ -1,20 +1,15 @@
import sys
from contextlib import AsyncExitStack as AsyncExitStack # noqa
from contextlib import asynccontextmanager as asynccontextmanager
from typing import AsyncGenerator, ContextManager, TypeVar
import anyio
from anyio import CapacityLimiter
from starlette.concurrency import iterate_in_threadpool as iterate_in_threadpool # noqa
from starlette.concurrency import run_in_threadpool as run_in_threadpool # noqa
from starlette.concurrency import ( # noqa
run_until_first_complete as run_until_first_complete,
)
if sys.version_info >= (3, 7):
from contextlib import AsyncExitStack as AsyncExitStack
from contextlib import asynccontextmanager as asynccontextmanager
else:
from contextlib2 import AsyncExitStack as AsyncExitStack # noqa
from contextlib2 import asynccontextmanager as asynccontextmanager # noqa
_T = TypeVar("_T")
@ -22,11 +17,24 @@ _T = TypeVar("_T")
async def contextmanager_in_threadpool(
cm: ContextManager[_T],
) -> AsyncGenerator[_T, None]:
# blocking __exit__ from running waiting on a free thread
# can create race conditions/deadlocks if the context manager itself
# has it's own internal pool (e.g. a database connection pool)
# to avoid this we let __exit__ run without a capacity limit
# since we're creating a new limiter for each call, any non-zero limit
# works (1 is arbitrary)
exit_limiter = CapacityLimiter(1)
try:
yield await run_in_threadpool(cm.__enter__)
except Exception as e:
ok: bool = await run_in_threadpool(cm.__exit__, type(e), e, None)
ok = bool(
await anyio.to_thread.run_sync(
cm.__exit__, type(e), e, None, limiter=exit_limiter
)
)
if not ok:
raise e
else:
await run_in_threadpool(cm.__exit__, None, None, None)
await anyio.to_thread.run_sync(
cm.__exit__, None, None, None, limiter=exit_limiter
)

15
fastapi/dependencies/utils.py

@ -7,6 +7,7 @@ from typing import (
Callable,
Coroutine,
Dict,
ForwardRef,
List,
Mapping,
Optional,
@ -47,7 +48,7 @@ from pydantic.fields import (
Undefined,
)
from pydantic.schema import get_annotation_from_field_info
from pydantic.typing import ForwardRef, evaluate_forwardref
from pydantic.typing import evaluate_forwardref
from pydantic.utils import lenient_issubclass
from starlette.background import BackgroundTasks
from starlette.concurrency import run_in_threadpool
@ -449,22 +450,22 @@ def is_coroutine_callable(call: Callable[..., Any]) -> bool:
return inspect.iscoroutinefunction(call)
if inspect.isclass(call):
return False
call = getattr(call, "__call__", None)
return inspect.iscoroutinefunction(call)
dunder_call = getattr(call, "__call__", None)
return inspect.iscoroutinefunction(dunder_call)
def is_async_gen_callable(call: Callable[..., Any]) -> bool:
if inspect.isasyncgenfunction(call):
return True
call = getattr(call, "__call__", None)
return inspect.isasyncgenfunction(call)
dunder_call = getattr(call, "__call__", None)
return inspect.isasyncgenfunction(dunder_call)
def is_gen_callable(call: Callable[..., Any]) -> bool:
if inspect.isgeneratorfunction(call):
return True
call = getattr(call, "__call__", None)
return inspect.isgeneratorfunction(call)
dunder_call = getattr(call, "__call__", None)
return inspect.isgeneratorfunction(dunder_call)
async def solve_generator(

10
fastapi/encoders.py

@ -54,8 +54,8 @@ def jsonable_encoder(
if custom_encoder:
encoder.update(custom_encoder)
obj_dict = obj.dict(
include=include, # type: ignore # in Pydantic
exclude=exclude, # type: ignore # in Pydantic
include=include,
exclude=exclude,
by_alias=by_alias,
exclude_unset=exclude_unset,
exclude_none=exclude_none,
@ -74,8 +74,12 @@ def jsonable_encoder(
obj_dict = dataclasses.asdict(obj)
return jsonable_encoder(
obj_dict,
exclude_none=exclude_none,
include=include,
exclude=exclude,
by_alias=by_alias,
exclude_unset=exclude_unset,
exclude_defaults=exclude_defaults,
exclude_none=exclude_none,
custom_encoder=custom_encoder,
sqlalchemy_safe=sqlalchemy_safe,
)

16
fastapi/exception_handlers.py

@ -1,19 +1,19 @@
from fastapi.encoders import jsonable_encoder
from fastapi.exceptions import RequestValidationError
from fastapi.utils import is_body_allowed_for_status_code
from starlette.exceptions import HTTPException
from starlette.requests import Request
from starlette.responses import JSONResponse
from starlette.responses import JSONResponse, Response
from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY
async def http_exception_handler(request: Request, exc: HTTPException) -> JSONResponse:
async def http_exception_handler(request: Request, exc: HTTPException) -> Response:
headers = getattr(exc, "headers", None)
if headers:
return JSONResponse(
{"detail": exc.detail}, status_code=exc.status_code, headers=headers
)
else:
return JSONResponse({"detail": exc.detail}, status_code=exc.status_code)
if not is_body_allowed_for_status_code(exc.status_code):
return Response(status_code=exc.status_code, headers=headers)
return JSONResponse(
{"detail": exc.detail}, status_code=exc.status_code, headers=headers
)
async def request_validation_exception_handler(

4
fastapi/routing.py

@ -127,7 +127,7 @@ async def serialize_response(
if is_coroutine:
value, errors_ = field.validate(response_content, {}, loc=("response",))
else:
value, errors_ = await run_in_threadpool( # type: ignore[misc]
value, errors_ = await run_in_threadpool(
field.validate, response_content, {}, loc=("response",)
)
if isinstance(errors_, ErrorWrapper):
@ -258,7 +258,7 @@ def get_request_handler(
is_coroutine=is_coroutine,
)
response = actual_response_class(content, **response_args)
if not is_body_allowed_for_status_code(status_code):
if not is_body_allowed_for_status_code(response.status_code):
response.body = b""
response.headers.raw.extend(sub_response.headers.raw)
return response

2
fastapi/security/api_key.py

@ -27,7 +27,7 @@ class APIKeyQuery(APIKeyBase):
self.auto_error = auto_error
async def __call__(self, request: Request) -> Optional[str]:
api_key: str = request.query_params.get(self.model.name)
api_key = request.query_params.get(self.model.name)
if not api_key:
if self.auto_error:
raise HTTPException(

10
fastapi/utils.py

@ -21,6 +21,16 @@ if TYPE_CHECKING: # pragma: nocover
def is_body_allowed_for_status_code(status_code: Union[int, str, None]) -> bool:
if status_code is None:
return True
# Ref: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#patterned-fields-1
if status_code in {
"default",
"1XX",
"2XX",
"3XX",
"4XX",
"5XX",
}:
return True
current_status_code = int(status_code)
return not (current_status_code < 200 or current_status_code in {204, 304})

1
fastapi/websockets.py

@ -1,2 +1,3 @@
from starlette.websockets import WebSocket as WebSocket # noqa
from starlette.websockets import WebSocketDisconnect as WebSocketDisconnect # noqa
from starlette.websockets import WebSocketState as WebSocketState # noqa

66
pyproject.toml

@ -1,12 +1,16 @@
[build-system]
requires = ["flit"]
build-backend = "flit.buildapi"
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.flit.metadata]
module = "fastapi"
author = "Sebastián Ramírez"
author-email = "[email protected]"
home-page = "https://github.com/tiangolo/fastapi"
[project]
name = "fastapi"
description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
readme = "README.md"
requires-python = ">=3.7"
license = "MIT"
authors = [
{ name = "Sebastián Ramírez", email = "[email protected]" },
]
classifiers = [
"Intended Audience :: Information Technology",
"Intended Audience :: System Administrators",
@ -26,7 +30,6 @@ classifiers = [
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
@ -34,40 +37,44 @@ classifiers = [
"Topic :: Internet :: WWW/HTTP :: HTTP Servers",
"Topic :: Internet :: WWW/HTTP",
]
requires = [
"starlette==0.19.1",
dependencies = [
"starlette==0.20.4",
"pydantic >=1.6.2,!=1.7,!=1.7.1,!=1.7.2,!=1.7.3,!=1.8,!=1.8.1,<2.0.0",
]
description-file = "README.md"
requires-python = ">=3.6.1"
dynamic = ["version"]
[tool.flit.metadata.urls]
[project.urls]
Homepage = "https://github.com/tiangolo/fastapi"
Documentation = "https://fastapi.tiangolo.com/"
[tool.flit.metadata.requires-extra]
[project.optional-dependencies]
test = [
"pytest >=6.2.4,<7.0.0",
"pytest >=7.1.3,<8.0.0",
"pytest-cov >=2.12.0,<4.0.0",
"mypy ==0.910",
"mypy ==0.971",
"flake8 >=3.8.3,<6.0.0",
"black == 22.3.0",
"black == 22.8.0",
"isort >=5.0.6,<6.0.0",
"requests >=2.24.0,<3.0.0",
"httpx >=0.14.0,<0.19.0",
"httpx >=0.23.0,<0.24.0",
"email_validator >=1.1.1,<2.0.0",
"sqlalchemy >=1.3.18,<1.5.0",
# TODO: once removing databases from tutorial, upgrade SQLAlchemy
# probably when including SQLModel
"sqlalchemy >=1.3.18,<=1.4.41",
"peewee >=3.13.3,<4.0.0",
"databases[sqlite] >=0.3.2,<0.6.0",
"databases[sqlite] >=0.3.2,<0.7.0",
"orjson >=3.2.1,<4.0.0",
"ujson >=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0,<6.0.0",
"python-multipart >=0.0.5,<0.0.6",
"flask >=1.1.2,<3.0.0",
"anyio[trio] >=3.2.1,<4.0.0",
"python-jose[cryptography] >=3.3.0,<4.0.0",
"pyyaml >=5.3.1,<7.0.0",
"passlib[bcrypt] >=1.7.2,<2.0.0",
# types
"types-ujson ==4.2.1",
"types-ujson ==5.4.0",
"types-orjson ==3.6.2",
"types-dataclasses ==0.6.5; python_version<'3.7'",
]
doc = [
"mkdocs >=1.1.2,<2.0.0",
@ -76,15 +83,13 @@ doc = [
"mkdocs-markdownextradata-plugin >=0.1.7,<0.3.0",
# TODO: upgrade and enable typer-cli once it supports Click 8.x.x
# "typer-cli >=0.0.12,<0.0.13",
"typer >=0.4.1,<0.5.0",
"typer[all] >=0.6.1,<0.7.0",
"pyyaml >=5.3.1,<7.0.0",
]
dev = [
"python-jose[cryptography] >=3.3.0,<4.0.0",
"passlib[bcrypt] >=1.7.2,<2.0.0",
"autoflake >=1.4.0,<2.0.0",
"flake8 >=3.8.3,<6.0.0",
"uvicorn[standard] >=0.12.0,<0.18.0",
"uvicorn[standard] >=0.12.0,<0.19.0",
"pre-commit >=2.17.0,<3.0.0",
]
all = [
@ -96,9 +101,12 @@ all = [
"ujson >=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0,<6.0.0",
"orjson >=3.2.1,<4.0.0",
"email_validator >=1.1.1,<2.0.0",
"uvicorn[standard] >=0.12.0,<0.18.0",
"uvicorn[standard] >=0.12.0,<0.19.0",
]
[tool.hatch.version]
path = "fastapi/__init__.py"
[tool.isort]
profile = "black"
known_third_party = ["fastapi", "pydantic", "starlette"]
@ -128,6 +136,6 @@ filterwarnings = [
# TODO: needed by asyncio in Python 3.9.7 https://bugs.python.org/issue45097, try to remove on 3.9.8
'ignore:The loop argument is deprecated since Python 3\.8, and scheduled for removal in Python 3\.10:DeprecationWarning:asyncio',
'ignore:starlette.middleware.wsgi is deprecated and will be removed in a future release\..*:DeprecationWarning:starlette',
# TODO: remove after dropping support for Python 3.6
'ignore:Python 3.6 is no longer supported by the Python core team. Therefore, support for it is deprecated in cryptography and will be removed in a future release.:UserWarning:jose',
# see https://trio.readthedocs.io/en/stable/history.html#trio-0-22-0-2022-09-28
'ignore::trio.TrioDeprecationWarning',
]

5
scripts/docs.py

@ -1,6 +1,7 @@
import os
import re
import shutil
import subprocess
from http.server import HTTPServer, SimpleHTTPRequestHandler
from multiprocessing import Pool
from pathlib import Path
@ -200,7 +201,7 @@ def build_lang(
)
current_dir = os.getcwd()
os.chdir(build_lang_path)
mkdocs.commands.build.build(mkdocs.config.load_config(site_dir=str(dist_path)))
subprocess.run(["mkdocs", "build", "--site-dir", dist_path], check=True)
os.chdir(current_dir)
typer.secho(f"Successfully built docs for: {lang}", color=typer.colors.GREEN)
@ -275,7 +276,7 @@ def build_all():
current_dir = os.getcwd()
os.chdir(en_docs_path)
typer.echo("Building docs for: en")
mkdocs.commands.build.build(mkdocs.config.load_config(site_dir=str(site_path)))
subprocess.run(["mkdocs", "build", "--site-dir", site_path], check=True)
os.chdir(current_dir)
langs = []
for lang in get_lang_paths():

63
tests/test_additional_responses_router.py

@ -1,5 +1,11 @@
from fastapi import APIRouter, FastAPI
from fastapi.testclient import TestClient
from pydantic import BaseModel
class ResponseModel(BaseModel):
message: str
app = FastAPI()
router = APIRouter()
@ -33,6 +39,18 @@ async def c():
return "c"
@router.get(
"/d",
responses={
"400": {"description": "Error with str"},
"5XX": {"model": ResponseModel},
"default": {"model": ResponseModel},
},
)
async def d():
return "d"
app.include_router(router)
openapi_schema = {
@ -81,6 +99,45 @@ openapi_schema = {
"operationId": "c_c_get",
}
},
"/d": {
"get": {
"responses": {
"400": {"description": "Error with str"},
"5XX": {
"description": "Server Error",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/ResponseModel"}
}
},
},
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
},
"default": {
"description": "Default Response",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/ResponseModel"}
}
},
},
},
"summary": "D",
"operationId": "d_d_get",
}
},
},
"components": {
"schemas": {
"ResponseModel": {
"title": "ResponseModel",
"required": ["message"],
"type": "object",
"properties": {"message": {"title": "Message", "type": "string"}},
}
}
},
}
@ -109,3 +166,9 @@ def test_c():
response = client.get("/c")
assert response.status_code == 200, response.text
assert response.json() == "c"
def test_d():
response = client.get("/d")
assert response.status_code == 200, response.text
assert response.json() == "d"

16
tests/test_jsonable_encoder.py

@ -1,3 +1,4 @@
from dataclasses import dataclass
from datetime import datetime, timezone
from enum import Enum
from pathlib import PurePath, PurePosixPath, PureWindowsPath
@ -19,6 +20,12 @@ class Pet:
self.name = name
@dataclass
class Item:
name: str
count: int
class DictablePerson(Person):
def __iter__(self):
return ((k, v) for k, v in self.__dict__.items())
@ -131,6 +138,15 @@ def test_encode_dictable():
}
def test_encode_dataclass():
item = Item(name="foo", count=100)
assert jsonable_encoder(item) == {"name": "foo", "count": 100}
assert jsonable_encoder(item, include={"name"}) == {"name": "foo"}
assert jsonable_encoder(item, exclude={"count"}) == {"name": "foo"}
assert jsonable_encoder(item, include={}) == {}
assert jsonable_encoder(item, exclude={}) == {"name": "foo", "count": 100}
def test_encode_unsupported():
unserializable = Unserializable()
with pytest.raises(ValueError):

97
tests/test_reponse_set_reponse_code_empty.py

@ -0,0 +1,97 @@
from typing import Any
from fastapi import FastAPI, Response
from fastapi.testclient import TestClient
app = FastAPI()
@app.delete(
"/{id}",
status_code=204,
)
async def delete_deployment(
id: int,
response: Response,
) -> Any:
response.status_code = 400
return {"msg": "Status overwritten", "id": id}
client = TestClient(app)
openapi_schema = {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/{id}": {
"delete": {
"summary": "Delete Deployment",
"operationId": "delete_deployment__id__delete",
"parameters": [
{
"required": True,
"schema": {"title": "Id", "type": "integer"},
"name": "id",
"in": "path",
}
],
"responses": {
"204": {"description": "Successful Response"},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
}
}
},
"components": {
"schemas": {
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {"$ref": "#/components/schemas/ValidationError"},
}
},
},
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
},
},
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_dependency_set_status_code():
response = client.delete("/1")
assert response.status_code == 400 and response.content
assert response.json() == {"msg": "Status overwritten", "id": 1}

46
tests/test_starlette_exception.py

@ -18,6 +18,16 @@ async def read_item(item_id: str):
return {"item": items[item_id]}
@app.get("/http-no-body-statuscode-exception")
async def no_body_status_code_exception():
raise HTTPException(status_code=204)
@app.get("/http-no-body-statuscode-with-detail-exception")
async def no_body_status_code_with_detail_exception():
raise HTTPException(status_code=204, detail="I should just disappear!")
@app.get("/starlette-items/{item_id}")
async def read_starlette_item(item_id: str):
if item_id not in items:
@ -31,6 +41,30 @@ openapi_schema = {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/http-no-body-statuscode-exception": {
"get": {
"operationId": "no_body_status_code_exception_http_no_body_statuscode_exception_get",
"responses": {
"200": {
"content": {"application/json": {"schema": {}}},
"description": "Successful " "Response",
}
},
"summary": "No Body " "Status " "Code " "Exception",
}
},
"/http-no-body-statuscode-with-detail-exception": {
"get": {
"operationId": "no_body_status_code_with_detail_exception_http_no_body_statuscode_with_detail_exception_get",
"responses": {
"200": {
"content": {"application/json": {"schema": {}}},
"description": "Successful " "Response",
}
},
"summary": "No Body Status Code With Detail Exception",
}
},
"/items/{item_id}": {
"get": {
"responses": {
@ -154,3 +188,15 @@ def test_get_starlette_item_not_found():
assert response.status_code == 404, response.text
assert response.headers.get("x-error") is None
assert response.json() == {"detail": "Item not found"}
def test_no_body_status_code_exception_handlers():
response = client.get("/http-no-body-statuscode-exception")
assert response.status_code == 204
assert not response.content
def test_no_body_status_code_with_detail_exception_handlers():
response = client.get("/http-no-body-statuscode-with-detail-exception")
assert response.status_code == 204
assert not response.content

10
tests/test_tutorial/test_sql_databases_peewee/test_sql_databases_peewee.py

@ -5,8 +5,6 @@ from unittest.mock import MagicMock
import pytest
from fastapi.testclient import TestClient
from ...utils import needs_py37
openapi_schema = {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
@ -340,14 +338,12 @@ def client():
test_db.unlink()
@needs_py37
def test_openapi_schema(client):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
@needs_py37
def test_create_user(client):
test_user = {"email": "[email protected]", "password": "secret"}
response = client.post("/users/", json=test_user)
@ -359,7 +355,6 @@ def test_create_user(client):
assert response.status_code == 400, response.text
@needs_py37
def test_get_user(client):
response = client.get("/users/1")
assert response.status_code == 200, response.text
@ -368,13 +363,11 @@ def test_get_user(client):
assert "id" in data
@needs_py37
def test_inexistent_user(client):
response = client.get("/users/999")
assert response.status_code == 404, response.text
@needs_py37
def test_get_users(client):
response = client.get("/users/")
assert response.status_code == 200, response.text
@ -386,7 +379,6 @@ def test_get_users(client):
time.sleep = MagicMock()
@needs_py37
def test_get_slowusers(client):
response = client.get("/slowusers/")
assert response.status_code == 200, response.text
@ -395,7 +387,6 @@ def test_get_slowusers(client):
assert "id" in data[0]
@needs_py37
def test_create_item(client):
item = {"title": "Foo", "description": "Something that fights"}
response = client.post("/users/1/items/", json=item)
@ -419,7 +410,6 @@ def test_create_item(client):
assert item_to_check["description"] == item["description"]
@needs_py37
def test_read_items(client):
response = client.get("/items/")
assert response.status_code == 200, response.text

11
tests/test_union_inherited_body.py

@ -4,14 +4,6 @@ from fastapi import FastAPI
from fastapi.testclient import TestClient
from pydantic import BaseModel
from .utils import needs_py37
# In Python 3.6:
# u = Union[ExtendedItem, Item] == __main__.Item
# But in Python 3.7:
# u = Union[ExtendedItem, Item] == typing.Union[__main__.ExtendedItem, __main__.Item]
app = FastAPI()
@ -118,21 +110,18 @@ inherited_item_openapi_schema = {
}
@needs_py37
def test_inherited_item_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == inherited_item_openapi_schema
@needs_py37
def test_post_extended_item():
response = client.post("/items/", json={"name": "Foo", "age": 5})
assert response.status_code == 200, response.text
assert response.json() == {"item": {"name": "Foo", "age": 5}}
@needs_py37
def test_post_item():
response = client.post("/items/", json={"name": "Foo"})
assert response.status_code == 200, response.text

1
tests/utils.py

@ -2,7 +2,6 @@ import sys
import pytest
needs_py37 = pytest.mark.skipif(sys.version_info < (3, 7), reason="requires python3.7+")
needs_py39 = pytest.mark.skipif(sys.version_info < (3, 9), reason="requires python3.9+")
needs_py310 = pytest.mark.skipif(
sys.version_info < (3, 10), reason="requires python3.10+"

Loading…
Cancel
Save