Compare commits
167 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0696454445 | ||
|
|
a145d3d277 | ||
|
|
453471d07b | ||
|
|
938b1a3542 | ||
|
|
4ce27b5d4d | ||
|
|
f9134fe5e4 | ||
|
|
d8ca285f8d | ||
|
|
1233a7d93b | ||
|
|
38902407c0 | ||
|
|
4fa0cd4def | ||
|
|
edd38c0230 | ||
|
|
8f90e514f4 | ||
|
|
fa1ffa5677 | ||
|
|
c0d6865c10 | ||
|
|
8a353ab911 | ||
|
|
262183b534 | ||
|
|
faf7ce5af5 | ||
|
|
3d201623dd | ||
|
|
59fbdefd7f | ||
|
|
e5980a71c2 | ||
|
|
0d1be46481 | ||
|
|
4fa4432173 | ||
|
|
c9eda31dd6 | ||
|
|
f2bc805113 | ||
|
|
8fc4872c1b | ||
|
|
b017a33ebd | ||
|
|
424674a082 | ||
|
|
944f06a901 | ||
|
|
3279ef38ed | ||
|
|
d286e6a5be | ||
|
|
b1c5b64c2c | ||
|
|
2ef0b9896e | ||
|
|
d07422a07a | ||
|
|
8724c493d9 | ||
|
|
df50d7c13f | ||
|
|
e0962d0b54 | ||
|
|
b7d5746773 | ||
|
|
3005c8c7b9 | ||
|
|
260d97ec6f | ||
|
|
f4620c42cf | ||
|
|
65ed4b5433 | ||
|
|
12342888d6 | ||
|
|
ee4e27a94f | ||
|
|
86fa3cb24f | ||
|
|
9090c771ee | ||
|
|
8df8b037f2 | ||
|
|
792285a047 | ||
|
|
66f6344820 | ||
|
|
b44e85ca8a | ||
|
|
33d61430cf | ||
|
|
146f57b8f7 | ||
|
|
1920c3dd16 | ||
|
|
07b12c8e41 | ||
|
|
4642d5bb86 | ||
|
|
0fd99ec337 | ||
|
|
7c8383c96b | ||
|
|
2b54432a9c | ||
|
|
acd2287b57 | ||
|
|
1d106bd959 | ||
|
|
77fc14eb69 | ||
|
|
41d75b6d1c | ||
|
|
ddd9da3db4 | ||
|
|
197c1d6dd7 | ||
|
|
d9e7a541fd | ||
|
|
c449ae5c74 | ||
|
|
1d8d81a6d5 | ||
|
|
d81c908132 | ||
|
|
cb4da93643 | ||
|
|
3cbfae16cf | ||
|
|
0def8382b8 | ||
|
|
02fae6a38e | ||
|
|
75af472029 | ||
|
|
e1135eddb5 | ||
|
|
acf8a91c25 | ||
|
|
c4f361c0c4 | ||
|
|
cc57bfcf60 | ||
|
|
26f725d259 | ||
|
|
9e018c322c | ||
|
|
3fefc83d42 | ||
|
|
2c31667407 | ||
|
|
233214795a | ||
|
|
e1d0e3874b | ||
|
|
eddbae948f | ||
|
|
5c842586c2 | ||
|
|
fc96370ce3 | ||
|
|
d820267cde | ||
|
|
bd94d313c9 | ||
|
|
2b6f1585ec | ||
|
|
bab5c201da | ||
|
|
aec2d26bac | ||
|
|
d5d6eebd40 | ||
|
|
7982aa5143 | ||
|
|
fd6ce67392 | ||
|
|
d3eb787090 | ||
|
|
6125dc72cd | ||
|
|
cf8b40e660 | ||
|
|
fab2a765de | ||
|
|
9aa698aa67 | ||
|
|
87e29ec2c5 | ||
|
|
abd148f63a | ||
|
|
9f38a05954 | ||
|
|
c89dc736bd | ||
|
|
19769d0483 | ||
|
|
586d17bfb5 | ||
|
|
786b5858e5 | ||
|
|
8a0d4c79c1 | ||
|
|
440d2d2d1a | ||
|
|
e953059054 | ||
|
|
f5d7df3c6c | ||
|
|
1ce16c2f40 | ||
|
|
03d4d4c38e | ||
|
|
2d2f1dee5d | ||
|
|
59e36481dc | ||
|
|
4fcb00328c | ||
|
|
9d56a3cb59 | ||
|
|
78b07cb809 | ||
|
|
6034f80687 | ||
|
|
b93f8a709a | ||
|
|
618c99d774 | ||
|
|
291180bf2d | ||
|
|
cbe8d552c1 | ||
|
|
af18d5c49f | ||
|
|
a698908ed6 | ||
|
|
dba9ea8120 | ||
|
|
f8d4d04015 | ||
|
|
5a864d8261 | ||
|
|
1bf55200a9 | ||
|
|
59b1f353b3 | ||
|
|
569afb4378 | ||
|
|
0f8349fcb7 | ||
|
|
6215fdd39e | ||
|
|
94ca8c1e29 | ||
|
|
f4963f05bf | ||
|
|
d4608a00cf | ||
|
|
699b5ef841 | ||
|
|
3de0fb82bf | ||
|
|
85518bc58b | ||
|
|
ca5d57ea79 | ||
|
|
347e391271 | ||
|
|
a75d080124 | ||
|
|
f0388915a8 | ||
|
|
9e2f5c67b6 | ||
|
|
93e4a19e35 | ||
|
|
e1c6d7d310 | ||
|
|
d23b295b96 | ||
|
|
26e94116c1 | ||
|
|
24968937e5 | ||
|
|
5c5b889288 | ||
|
|
436261b3ea | ||
|
|
5c62a59e7b | ||
|
|
acbe79da37 | ||
|
|
a85aa125d2 | ||
|
|
9af8cc69d5 | ||
|
|
7fe79441c1 | ||
|
|
b8ae84d460 | ||
|
|
ca2b1dbb64 | ||
|
|
672c55ac62 | ||
|
|
66c27c3e07 | ||
|
|
44f4885c66 | ||
|
|
4da33e3031 | ||
|
|
a1ede32f29 | ||
|
|
0a82b3a900 | ||
|
|
d08a062ee2 | ||
|
|
83f6781037 | ||
|
|
764ecae2d4 | ||
|
|
4e9f75912f | ||
|
|
2b10ca1cc4 |
@@ -13,3 +13,4 @@ pl: 3169
|
||||
de: 3716
|
||||
id: 3717
|
||||
az: 3994
|
||||
nl: 4701
|
||||
|
||||
17
.github/actions/people/app/main.py
vendored
@@ -501,9 +501,16 @@ if __name__ == "__main__":
|
||||
github_sponsors_path = Path("./docs/en/data/github_sponsors.yml")
|
||||
people_old_content = people_path.read_text(encoding="utf-8")
|
||||
github_sponsors_old_content = github_sponsors_path.read_text(encoding="utf-8")
|
||||
new_people_content = yaml.dump(people, sort_keys=False, width=200, allow_unicode=True)
|
||||
new_github_sponsors_content = yaml.dump(github_sponsors, sort_keys=False, width=200, allow_unicode=True)
|
||||
if people_old_content == new_people_content and github_sponsors_old_content == new_github_sponsors_content:
|
||||
new_people_content = yaml.dump(
|
||||
people, sort_keys=False, width=200, allow_unicode=True
|
||||
)
|
||||
new_github_sponsors_content = yaml.dump(
|
||||
github_sponsors, sort_keys=False, width=200, allow_unicode=True
|
||||
)
|
||||
if (
|
||||
people_old_content == new_people_content
|
||||
and github_sponsors_old_content == new_github_sponsors_content
|
||||
):
|
||||
logging.info("The FastAPI People data hasn't changed, finishing.")
|
||||
sys.exit(0)
|
||||
people_path.write_text(new_people_content, encoding="utf-8")
|
||||
@@ -517,7 +524,9 @@ if __name__ == "__main__":
|
||||
logging.info(f"Creating a new branch {branch_name}")
|
||||
subprocess.run(["git", "checkout", "-b", branch_name], check=True)
|
||||
logging.info("Adding updated file")
|
||||
subprocess.run(["git", "add", str(people_path)], check=True)
|
||||
subprocess.run(
|
||||
["git", "add", str(people_path), str(github_sponsors_path)], check=True
|
||||
)
|
||||
logging.info("Committing updated file")
|
||||
message = "👥 Update FastAPI People"
|
||||
result = subprocess.run(["git", "commit", "-m", message], check=True)
|
||||
|
||||
4
.github/workflows/build-docs.yml
vendored
@@ -1,6 +1,8 @@
|
||||
name: Build Docs
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
jobs:
|
||||
@@ -20,7 +22,7 @@ jobs:
|
||||
id: cache
|
||||
with:
|
||||
path: ${{ env.pythonLocation }}
|
||||
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-docs
|
||||
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-docs-v2
|
||||
- name: Install Flit
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: python3.7 -m pip install flit
|
||||
|
||||
6
.github/workflows/test.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.6, 3.7, 3.8, 3.9]
|
||||
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"]
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
id: cache
|
||||
with:
|
||||
path: ${{ env.pythonLocation }}
|
||||
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-test
|
||||
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
|
||||
@@ -38,4 +38,4 @@ jobs:
|
||||
- name: Test
|
||||
run: bash scripts/test.sh
|
||||
- name: Upload coverage
|
||||
uses: codecov/codecov-action@v1
|
||||
uses: codecov/codecov-action@v2
|
||||
|
||||
@@ -49,12 +49,15 @@ The key features are:
|
||||
|
||||
<a href="https://bit.ly/2QSouzH" target="_blank" title="Jina: build neural search-as-a-service for any kind of data in just minutes."><img src="https://fastapi.tiangolo.com/img/sponsors/jina.svg"></a>
|
||||
<a href="https://cryptapi.io/" target="_blank" title="CryptAPI: Your easy to use, secure and privacy oriented payment gateway."><img src="https://fastapi.tiangolo.com/img/sponsors/cryptapi.svg"></a>
|
||||
<a href="https://classiq.link/n4s" target="_blank" title="Join the team building a new SaaS platform that will change the computing world"><img src="https://fastapi.tiangolo.com/img/sponsors/classiq.png"></a>
|
||||
<a href="https://www.dropbase.io/careers" target="_blank" title="Dropbase - seamlessly collect, clean, and centralize data."><img src="https://fastapi.tiangolo.com/img/sponsors/dropbase.svg"></a>
|
||||
<a href="https://www.deta.sh/?ref=fastapi" target="_blank" title="The launchpad for all your (team's) ideas"><img src="https://fastapi.tiangolo.com/img/sponsors/deta.svg"></a>
|
||||
<a href="https://www.investsuite.com/jobs" target="_blank" title="Wealthtech jobs with FastAPI"><img src="https://fastapi.tiangolo.com/img/sponsors/investsuite.svg"></a>
|
||||
<a href="https://www.vim.so/?utm_source=FastAPI" target="_blank" title="We help you master vim with interactive exercises"><img src="https://fastapi.tiangolo.com/img/sponsors/vimso.png"></a>
|
||||
<a href="https://talkpython.fm/fastapi-sponsor" target="_blank" title="FastAPI video courses on demand from people you trust"><img src="https://fastapi.tiangolo.com/img/sponsors/talkpython.png"></a>
|
||||
<a href="https://training.talkpython.fm/fastapi-courses" target="_blank" title="FastAPI video courses on demand from people you trust"><img src="https://fastapi.tiangolo.com/img/sponsors/talkpython.png"></a>
|
||||
<a href="https://testdriven.io/courses/tdd-fastapi/" target="_blank" title="Learn to build high-quality web apps with best practices"><img src="https://fastapi.tiangolo.com/img/sponsors/testdriven.svg"></a>
|
||||
<a href="https://github.com/deepset-ai/haystack/" target="_blank" title="Build powerful search from composable, open source building blocks"><img src="https://fastapi.tiangolo.com/img/sponsors/haystack-fastapi.svg"></a>
|
||||
<a href="https://www.udemy.com/course/fastapi-rest/" target="_blank" title="Learn FastAPI by building a complete project. Extend your knowledge on advanced web development-AWS, Payments, Emails."><img src="https://fastapi.tiangolo.com/img/sponsors/ines-course.jpg"></a>
|
||||
<a href="https://careers.budget-insight.com/" target="_blank" title="Budget Insight is hiring!"><img src="https://fastapi.tiangolo.com/img/sponsors/budget-insight.svg"></a>
|
||||
|
||||
<!-- /sponsors -->
|
||||
|
||||
|
||||
@@ -29,9 +29,6 @@ theme:
|
||||
repo_name: tiangolo/fastapi
|
||||
repo_url: https://github.com/tiangolo/fastapi
|
||||
edit_uri: ''
|
||||
google_analytics:
|
||||
- UA-133183413-1
|
||||
- auto
|
||||
plugins:
|
||||
- search
|
||||
- markdownextradata:
|
||||
@@ -43,11 +40,13 @@ nav:
|
||||
- az: /az/
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fa: /fa/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
- ru: /ru/
|
||||
@@ -70,8 +69,12 @@ markdown_extensions:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
extra:
|
||||
analytics:
|
||||
provider: google
|
||||
property: UA-133183413-1
|
||||
social:
|
||||
- icon: fontawesome/brands/github-alt
|
||||
link: https://github.com/tiangolo/fastapi
|
||||
@@ -96,6 +99,8 @@ extra:
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fa/
|
||||
name: fa
|
||||
- link: /fr/
|
||||
name: fr - français
|
||||
- link: /id/
|
||||
@@ -106,6 +111,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
name: pl
|
||||
- link: /pt/
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
### Automatische Dokumentation
|
||||
|
||||
Mit einer interaktiven API-Dokumentation und explorativen webbasierten Benutzerschnittstellen. Da FastAPI auf OpenAPI basiert, gibt es hierzu mehrere Optionen, wobei zwei standartmäßig vorhanden sind.
|
||||
Mit einer interaktiven API-Dokumentation und explorativen webbasierten Benutzerschnittstellen. Da FastAPI auf OpenAPI basiert, gibt es hierzu mehrere Optionen, wobei zwei standardmäßig vorhanden sind.
|
||||
|
||||
* <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank"><strong>Swagger UI</strong></a>, bietet interaktive Exploration: testen und rufen Sie ihre API direkt vom Webbrowser auf.
|
||||
|
||||
@@ -97,9 +97,9 @@ Hierdurch werden Sie nie wieder einen falschen Schlüsselnamen benutzen und spar
|
||||
|
||||
### Kompakt
|
||||
|
||||
FastAPI nutzt für alles sensible **Standard-Einstellungen**, welche optional überall konfiguriert werden können. Alle Parameter können ganz genau an Ihre Bedürfnisse angepasst werden, sodass sie genau die API definieren können, die sie brachen.
|
||||
FastAPI nutzt für alles sinnvolle **Standard-Einstellungen**, welche optional überall konfiguriert werden können. Alle Parameter können ganz genau an Ihre Bedürfnisse angepasst werden, sodass sie genau die API definieren können, die sie brauchen.
|
||||
|
||||
Aber standartmäßig, **"funktioniert einfach"** alles.
|
||||
Aber standardmäßig, **"funktioniert einfach"** alles.
|
||||
|
||||
### Validierung
|
||||
|
||||
@@ -109,7 +109,7 @@ Aber standartmäßig, **"funktioniert einfach"** alles.
|
||||
* Zeichenketten (`str`), mit definierter minimaler und maximaler Länge.
|
||||
* Zahlen (`int`, `float`) mit minimaler und maximaler Größe, usw.
|
||||
|
||||
* Validierung für ungewögnliche Typen, wie:
|
||||
* Validierung für ungewöhnliche Typen, wie:
|
||||
* URL.
|
||||
* Email.
|
||||
* UUID.
|
||||
@@ -142,8 +142,8 @@ FastAPI enthält ein extrem einfaches, aber extrem mächtiges <abbr title='oft v
|
||||
* **Automatische Umsetzung** durch FastAPI.
|
||||
* Alle abhängigen Komponenten könnten Daten von Anfragen, **Erweiterungen der Pfadoperations-**Einschränkungen und der automatisierten Dokumentation benötigen.
|
||||
* **Automatische Validierung** selbst für *Pfadoperationen*-Parameter, die in den Abhängigkeiten definiert wurden.
|
||||
* Unterstütz komplexe Benutzerauthentifizierungssysteme, mit **Datenbankverbindungen**, usw.
|
||||
* **Keine Kompromisse** bei Datenbanken, Eingabemasken, usw. Sondern einfache Integration von allen.
|
||||
* Unterstützt komplexe Benutzerauthentifizierungssysteme, mit **Datenbankverbindungen**, usw.
|
||||
* **Keine Kompromisse** bei Datenbanken, Eingabemasken, usw., sondern einfache Integration von allen.
|
||||
|
||||
### Unbegrenzte Erweiterungen
|
||||
|
||||
@@ -159,9 +159,9 @@ Jede Integration wurde so entworfen, dass sie einfach zu nutzen ist (mit Abhäng
|
||||
|
||||
## Starlette's Merkmale
|
||||
|
||||
**FastAPI** ist vollkommen kompatibel (und basiert auf) <a href="https://www.starlette.io/" class="external-link" target="_blank"><strong>Starlette</strong></a>. Das bedeutet, auch ihr eigner Starlett Quellcode funktioniert.
|
||||
**FastAPI** ist vollkommen kompatibel (und basiert auf) <a href="https://www.starlette.io/" class="external-link" target="_blank"><strong>Starlette</strong></a>. Das bedeutet, auch ihr eigener Starlette Quellcode funktioniert.
|
||||
|
||||
`FastAPI` ist eigentlich eine Unterklasse von `Starlette`. Wenn sie also bereits Starlette kennen oder benutzen, können Sie das meiste Ihres Wissen direkt anwenden.
|
||||
`FastAPI` ist eigentlich eine Unterklasse von `Starlette`. Wenn Sie also bereits Starlette kennen oder benutzen, können Sie das meiste Ihres Wissens direkt anwenden.
|
||||
|
||||
Mit **FastAPI** bekommen Sie viele von **Starlette**'s Funktionen (da FastAPI nur Starlette auf Steroiden ist):
|
||||
|
||||
@@ -199,5 +199,5 @@ Mit **FastAPI** bekommen Sie alle Funktionen von **Pydantic** (da FastAPI für d
|
||||
* Validierungen erlauben klare und einfache Datenschemadefinition, überprüft und dokumentiert als JSON Schema.
|
||||
* Sie können stark **verschachtelte JSON** Objekte haben und diese sind trotzdem validiert und annotiert.
|
||||
* **Erweiterbar**:
|
||||
* Pydantic erlaubt die Definition von eigenen Datentypen oder sie können die Validierung mit einer `validator` dekorierten Methode erweitern..
|
||||
* Pydantic erlaubt die Definition von eigenen Datentypen oder Sie können die Validierung mit einer `validator` dekorierten Methode erweitern..
|
||||
* 100% Testabdeckung.
|
||||
|
||||
@@ -446,7 +446,6 @@ Used by Pydantic:
|
||||
Used by Starlette:
|
||||
|
||||
* <a href="https://requests.readthedocs.io" target="_blank"><code>requests</code></a> - Required if you want to use the `TestClient`.
|
||||
* <a href="https://github.com/Tinche/aiofiles" target="_blank"><code>aiofiles</code></a> - Required if you want to use `FileResponse` or `StaticFiles`.
|
||||
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
|
||||
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`.
|
||||
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Required for `SessionMiddleware` support.
|
||||
|
||||
@@ -29,9 +29,6 @@ theme:
|
||||
repo_name: tiangolo/fastapi
|
||||
repo_url: https://github.com/tiangolo/fastapi
|
||||
edit_uri: ''
|
||||
google_analytics:
|
||||
- UA-133183413-1
|
||||
- auto
|
||||
plugins:
|
||||
- search
|
||||
- markdownextradata:
|
||||
@@ -43,11 +40,13 @@ nav:
|
||||
- az: /az/
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fa: /fa/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
- ru: /ru/
|
||||
@@ -71,8 +70,12 @@ markdown_extensions:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
extra:
|
||||
analytics:
|
||||
provider: google
|
||||
property: UA-133183413-1
|
||||
social:
|
||||
- icon: fontawesome/brands/github-alt
|
||||
link: https://github.com/tiangolo/fastapi
|
||||
@@ -97,6 +100,8 @@ extra:
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fa/
|
||||
name: fa
|
||||
- link: /fr/
|
||||
name: fr - français
|
||||
- link: /id/
|
||||
@@ -107,6 +112,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
name: pl
|
||||
- link: /pt/
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
articles:
|
||||
english:
|
||||
- author: Silvan Melchior
|
||||
author_link: https://github.com/silvanmelchior
|
||||
link: https://blog.devgenius.io/seamless-fastapi-configuration-with-confz-90949c14ea12
|
||||
title: Seamless FastAPI Configuration with ConfZ
|
||||
- author: Kaustubh Gupta
|
||||
author_link: https://medium.com/@kaustubhgupta1828/
|
||||
link: https://levelup.gitconnected.com/5-advance-features-of-fastapi-you-should-try-7c0ac7eebb3e
|
||||
title: 5 Advanced Features of FastAPI You Should Try
|
||||
- author: Kaustubh Gupta
|
||||
author_link: https://medium.com/@kaustubhgupta1828/
|
||||
link: https://www.analyticsvidhya.com/blog/2021/06/deploying-ml-models-as-api-using-fastapi-and-heroku/
|
||||
@@ -12,6 +20,10 @@ articles:
|
||||
author_link: https://pystar.substack.com/
|
||||
link: https://pystar.substack.com/p/how-to-create-a-fake-certificate
|
||||
title: How to Create A Fake Certificate Authority And Generate TLS Certs for FastAPI
|
||||
- author: Ben Gamble
|
||||
author_link: https://uk.linkedin.com/in/bengamble7
|
||||
link: https://ably.com/blog/realtime-ticket-booking-solution-kafka-fastapi-ably
|
||||
title: Building a realtime ticket booking solution with Kafka, FastAPI, and Ably
|
||||
- author: Shahriyar(Shako) Rzayev
|
||||
author_link: https://www.linkedin.com/in/shahriyar-rzayev/
|
||||
link: https://www.azepug.az/posts/fastapi/#building-simple-e-commerce-with-nuxtjs-and-fastapi-series
|
||||
|
||||
@@ -1,42 +1,75 @@
|
||||
sponsors:
|
||||
- - login: jina-ai
|
||||
- - login: cryptapi
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/44925437?u=61369138589bc7fee6c417f3fbd50fbd38286cc4&v=4
|
||||
url: https://github.com/cryptapi
|
||||
- login: jina-ai
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/60539444?v=4
|
||||
url: https://github.com/jina-ai
|
||||
- login: DropbaseHQ
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/85367855?v=4
|
||||
url: https://github.com/DropbaseHQ
|
||||
- - login: sushi2all
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1043732?v=4
|
||||
url: https://github.com/sushi2all
|
||||
- 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?v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2035561?u=1bb18268bcd4d9249e1f783a063c27df9a84c05b&v=4
|
||||
url: https://github.com/mikeckennedy
|
||||
- login: RodneyU215
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3329665?u=ec6a9adf8e7e8e306eed7d49687c398608d1604f&v=4
|
||||
url: https://github.com/RodneyU215
|
||||
- login: Trivie
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8161763?v=4
|
||||
url: https://github.com/Trivie
|
||||
- login: deta
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/47275976?v=4
|
||||
url: https://github.com/deta
|
||||
- login: deepset-ai
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/51827949?v=4
|
||||
url: https://github.com/deepset-ai
|
||||
- login: investsuite
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/73833632?v=4
|
||||
url: https://github.com/investsuite
|
||||
- login: vimsoHQ
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/77627231?v=4
|
||||
url: https://github.com/vimsoHQ
|
||||
- - login: newrelic
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31739?v=4
|
||||
url: https://github.com/newrelic
|
||||
- login: VincentParedes
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/103889729?v=4
|
||||
url: https://github.com/VincentParedes
|
||||
- - login: plocher
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1082871?v=4
|
||||
url: https://github.com/plocher
|
||||
- - login: InesIvanova
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/22920417?u=409882ec1df6dbd77455788bb383a8de223dbf6f&v=4
|
||||
url: https://github.com/InesIvanova
|
||||
- - 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: xoflare
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/74335107?v=4
|
||||
url: https://github.com/xoflare
|
||||
- login: Striveworks
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/45523576?v=4
|
||||
url: https://github.com/Striveworks
|
||||
- login: BoostryJP
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/57932412?v=4
|
||||
url: https://github.com/BoostryJP
|
||||
- - login: johnadjei
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/767860?v=4
|
||||
url: https://github.com/johnadjei
|
||||
- login: HiredScore
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3908850?v=4
|
||||
url: https://github.com/HiredScore
|
||||
- login: wdwinslow
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11562137?u=dc01daafb354135603a263729e3d26d939c0c452&v=4
|
||||
url: https://github.com/wdwinslow
|
||||
- - login: kamalgill
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/133923?u=0df9181d97436ce330e9acf90ab8a54b7022efe7&v=4
|
||||
url: https://github.com/kamalgill
|
||||
- - login: moellenbeck
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/169372?v=4
|
||||
url: https://github.com/moellenbeck
|
||||
- login: RodneyU215
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3329665?u=ec6a9adf8e7e8e306eed7d49687c398608d1604f&v=4
|
||||
url: https://github.com/RodneyU215
|
||||
- login: grillazz
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3415861?u=16d7d0ffa5dfb99f8834f8f76d90e138ba09b94a&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3415861?u=0b32b7073ae1ab8b7f6d2db0188c2e1e357ff451&v=4
|
||||
url: https://github.com/grillazz
|
||||
- login: tizz98
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5739698?u=f095a3659e3a8e7c69ccd822696990b521ea25f9&v=4
|
||||
@@ -44,45 +77,57 @@ sponsors:
|
||||
- login: jmaralc
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/21101214?u=b15a9f07b7cbf6c9dcdbcb6550bbd2c52f55aa50&v=4
|
||||
url: https://github.com/jmaralc
|
||||
- login: AlexandruSimion
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/71321732?v=4
|
||||
url: https://github.com/AlexandruSimion
|
||||
- - login: samuelcolvin
|
||||
- login: marutoraman
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/33813153?u=2d0522bceba0b8b69adf1f2db866503bd96f944e&v=4
|
||||
url: https://github.com/marutoraman
|
||||
- login: mainframeindustries
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/55092103?v=4
|
||||
url: https://github.com/mainframeindustries
|
||||
- login: A-Edge
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/59514131?v=4
|
||||
url: https://github.com/A-Edge
|
||||
- - login: Kludex
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
|
||||
url: https://github.com/Kludex
|
||||
- login: samuelcolvin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4039449?u=807390ba9cfe23906c3bf8a0d56aaca3cf2bfa0d&v=4
|
||||
url: https://github.com/samuelcolvin
|
||||
- login: jokull
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/701?u=0532b62166893d5160ef795c4c8b7512d971af05&v=4
|
||||
url: https://github.com/jokull
|
||||
- login: jefftriplett
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/50527?u=af1ddfd50f6afd6d99f333ba2ac8d0a5b245ea74&v=4
|
||||
url: https://github.com/jefftriplett
|
||||
- login: kamalgill
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/133923?u=0df9181d97436ce330e9acf90ab8a54b7022efe7&v=4
|
||||
url: https://github.com/kamalgill
|
||||
- login: jsutton
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/280777?v=4
|
||||
url: https://github.com/jsutton
|
||||
- login: deserat
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/299332?v=4
|
||||
url: https://github.com/deserat
|
||||
- login: ericof
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/306014?u=cf7c8733620397e6584a451505581c01c5d842d7&v=4
|
||||
url: https://github.com/ericof
|
||||
- login: wshayes
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
|
||||
url: https://github.com/wshayes
|
||||
- login: koxudaxi
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/630670?u=507d8577b4b3670546b449c4c2ccbc5af40d72f7&v=4
|
||||
url: https://github.com/koxudaxi
|
||||
- login: 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=e4835b2a985a0f2d52018e4926cb5a58c26a62e8&v=4
|
||||
url: https://github.com/jqueguiner
|
||||
- login: Mazyod
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/860511?v=4
|
||||
url: https://github.com/Mazyod
|
||||
- login: ltieman
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1084689?u=e69b17de17cb3ca141a17daa7ccbe173ceb1eb17&v=4
|
||||
url: https://github.com/ltieman
|
||||
- login: mrmattwright
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1277725?v=4
|
||||
url: https://github.com/mrmattwright
|
||||
- login: westonsteimel
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1593939?u=0f2c0e3647f916fe295d62fa70da7a4c177115e3&v=4
|
||||
url: https://github.com/westonsteimel
|
||||
- login: timdrijvers
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1694939?v=4
|
||||
url: https://github.com/timdrijvers
|
||||
- login: mrgnw
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2504532?u=7ec43837a6d0afa80f96f0788744ea6341b89f97&v=4
|
||||
url: https://github.com/mrgnw
|
||||
- login: corleyma
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2080732?u=aed2ff652294a87d666b1c3f6dbe98104db76d26&v=4
|
||||
url: https://github.com/corleyma
|
||||
- login: madisonmay
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2645393?u=f22b93c6ea345a4d26a90a3834dfc7f0789fcb63&v=4
|
||||
url: https://github.com/madisonmay
|
||||
@@ -93,149 +138,194 @@ sponsors:
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3148093?v=4
|
||||
url: https://github.com/andre1sk
|
||||
- login: Shark009
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3163309?v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3163309?u=0c6f4091b0eda05c44c390466199826e6dc6e431&v=4
|
||||
url: https://github.com/Shark009
|
||||
- login: dblackrun
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3528486?v=4
|
||||
url: https://github.com/dblackrun
|
||||
- login: zsinx6
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3532625?u=ba75a5dc744d1116ccfeaaf30d41cb2fe81fe8dd&v=4
|
||||
url: https://github.com/zsinx6
|
||||
- login: anomaly
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3654837?v=4
|
||||
url: https://github.com/anomaly
|
||||
- login: peterHoburg
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3860655?u=f55f47eb2d6a9b495e806ac5a044e3ae01ccc1fa&v=4
|
||||
url: https://github.com/peterHoburg
|
||||
- login: jaredtrog
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4381365?v=4
|
||||
url: https://github.com/jaredtrog
|
||||
- login: oliverxchen
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4471774?u=534191f25e32eeaadda22dfab4b0a428733d5489&v=4
|
||||
url: https://github.com/oliverxchen
|
||||
- login: CINOAdam
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4728508?u=34c3d58cb900fed475d0172b436c66a94ad739ed&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4728508?u=76ef23f06ae7c604e009873bc27cf0ea9ba738c9&v=4
|
||||
url: https://github.com/CINOAdam
|
||||
- login: dudil
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4785835?u=58b7ea39123e0507f3b2996448a27256b16fd697&v=4
|
||||
url: https://github.com/dudil
|
||||
- login: ScrimForever
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5040124?u=091ec38bfe16d6e762099e91309b59f248616a65&v=4
|
||||
url: https://github.com/ScrimForever
|
||||
- login: ennui93
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5300907?u=5b5452725ddb391b2caaebf34e05aba873591c3a&v=4
|
||||
url: https://github.com/ennui93
|
||||
- login: MacroPower
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5648814?u=e13991efd1e03c44c911f919872e750530ded633&v=4
|
||||
url: https://github.com/MacroPower
|
||||
- login: ginomempin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6091865?v=4
|
||||
url: https://github.com/ginomempin
|
||||
- login: Yaleesa
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6135475?v=4
|
||||
url: https://github.com/Yaleesa
|
||||
- login: iwpnd
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6152183?u=b2286006daafff5f991557344fee20b5da59639a&v=4
|
||||
url: https://github.com/iwpnd
|
||||
- login: simw
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6322526?v=4
|
||||
url: https://github.com/simw
|
||||
- login: pkucmus
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6347418?u=98f5918b32e214a168a2f5d59b0b8ebdf57dca0d&v=4
|
||||
url: https://github.com/pkucmus
|
||||
- login: s3ich4n
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6926298?u=ba3025d698e1c986655e776ae383a3d60d9d578e&v=4
|
||||
url: https://github.com/s3ich4n
|
||||
- login: Rehket
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7015688?u=3afb0ba200feebbc7f958950e92db34df2a3c172&v=4
|
||||
url: https://github.com/Rehket
|
||||
- login: christippett
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7218120?u=434b9d29287d7de25772d94ddc74a9bd6d969284&v=4
|
||||
url: https://github.com/christippett
|
||||
- login: Kludex
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=cf8455cb899806b774a3a71073f88583adec99f6&v=4
|
||||
url: https://github.com/Kludex
|
||||
- login: hiancdtrsnm
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7343177?v=4
|
||||
url: https://github.com/hiancdtrsnm
|
||||
- login: Shackelford-Arden
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7362263?v=4
|
||||
url: https://github.com/Shackelford-Arden
|
||||
- login: cristeaadrian
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9112724?v=4
|
||||
url: https://github.com/cristeaadrian
|
||||
- login: otivvormes
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11317418?u=6de1edefb6afd0108c0ad2816bd6efc4464a9c44&v=4
|
||||
url: https://github.com/otivvormes
|
||||
- login: iambobmae
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/12390270?u=c9a35c2ee5092a9b4135ebb1f91b7f521c467031&v=4
|
||||
url: https://github.com/iambobmae
|
||||
- login: ronaldnwilliams
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/13632749?u=ac41a086d0728bf66a9d2bee9e5e377041ff44a4&v=4
|
||||
url: https://github.com/ronaldnwilliams
|
||||
- login: Vikka
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9381120?u=4bfc7032a824d1ed1994aa8256dfa597c8f187ad&v=4
|
||||
url: https://github.com/Vikka
|
||||
- login: Ge0f3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11887760?u=ccd80f1ac36dcb8517ef5c4e702e8cc5a80cad2f&v=4
|
||||
url: https://github.com/Ge0f3
|
||||
- login: gokulyc
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/13468848?u=269f269d3e70407b5fb80138c52daba7af783997&v=4
|
||||
url: https://github.com/gokulyc
|
||||
- login: dannywade
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/13680237?u=418ee985bd41577b20fde81417fb2d901e875e8a&v=4
|
||||
url: https://github.com/dannywade
|
||||
- login: pablonnaoji
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/15187159?u=afc15bd5a4ba9c5c7206bbb1bcaeef606a0932e0&v=4
|
||||
url: https://github.com/pablonnaoji
|
||||
- login: natenka
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/15850513?u=00d1083c980d0b4ce32835dc07eee7f43f34fd2f&v=4
|
||||
url: https://github.com/natenka
|
||||
- login: la-mar
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16618300?u=7755c0521d2bb0d704f35a51464b15c1e2e6c4da&v=4
|
||||
url: https://github.com/la-mar
|
||||
- login: robintully
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/17059673?u=862b9bb01513f5acd30df97433cb97a24dbfb772&v=4
|
||||
url: https://github.com/robintully
|
||||
- login: ShaulAb
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/18129076?u=2c8d48e47f2dbee15c3f89c3d17d4c356504386c&v=4
|
||||
url: https://github.com/ShaulAb
|
||||
- login: wedwardbeck
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/19333237?u=1de4ae2bf8d59eb4c013f21d863cbe0f2010575f&v=4
|
||||
url: https://github.com/wedwardbeck
|
||||
- login: linusg
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/19366641?u=125e390abef8fff3b3b0d370c369cba5d7fd4c67&v=4
|
||||
url: https://github.com/linusg
|
||||
- login: stradivari96
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/19752586?u=255f5f06a768f518b20cebd6963e840ac49294fd&v=4
|
||||
url: https://github.com/stradivari96
|
||||
- login: RedCarpetUp
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/20360440?v=4
|
||||
url: https://github.com/RedCarpetUp
|
||||
- login: Filimoa
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/21352040?u=75e02d102d2ee3e3d793e555fa5c63045913ccb0&v=4
|
||||
url: https://github.com/Filimoa
|
||||
- login: raminsj13
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/24259406?u=d51f2a526312ebba150a06936ed187ca0727d329&v=4
|
||||
url: https://github.com/raminsj13
|
||||
- login: comoelcometa
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/25950317?u=c6751efa038561b9bc5fa56d1033d5174e10cd65&v=4
|
||||
url: https://github.com/comoelcometa
|
||||
- login: shuheng-liu
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/22414322?u=813c45f30786c6b511b21a661def025d8f7b609e&v=4
|
||||
url: https://github.com/shuheng-liu
|
||||
- login: cometa-haley
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/25950317?u=cec1a3e0643b785288ae8260cc295a85ab344995&v=4
|
||||
url: https://github.com/cometa-haley
|
||||
- login: LarryGF
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/26148349?u=431bb34d36d41c172466252242175281ae132152&v=4
|
||||
url: https://github.com/LarryGF
|
||||
- login: veprimk
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/29689749?u=f8cb5a15a286e522e5b189bc572d5a1a90217fb2&v=4
|
||||
url: https://github.com/veprimk
|
||||
- login: orihomie
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/29889683?u=6bc2135a52fcb3a49e69e7d50190796618185fda&v=4
|
||||
url: https://github.com/orihomie
|
||||
- login: SaltyCoco
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31451104?u=6ee4e17c07d21b7054f54a12fa9cc377a1b24ff9&v=4
|
||||
url: https://github.com/SaltyCoco
|
||||
- login: meysam81
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/30233243?u=64dc9fc62d039892c6fb44d804251cad5537132b&v=4
|
||||
url: https://github.com/meysam81
|
||||
- login: mauroalejandrojm
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31569442?u=cdada990a1527926a36e95f62c30a8b48bbc49a1&v=4
|
||||
url: https://github.com/mauroalejandrojm
|
||||
- login: bulkw4r3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/35562532?u=0b812a14a02de14bf73d05fb2b2760a67bacffc2&v=4
|
||||
url: https://github.com/bulkw4r3
|
||||
- login: Leay15
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/32212558?u=c4aa9c1737e515959382a5515381757b1fd86c53&v=4
|
||||
url: https://github.com/Leay15
|
||||
- login: AlrasheedA
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/33544979?u=7fe66bf62b47682612b222e3e8f4795ef3be769b&v=4
|
||||
url: https://github.com/AlrasheedA
|
||||
- login: ProteinQure
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/33707203?v=4
|
||||
url: https://github.com/ProteinQure
|
||||
- login: guligon90
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/35070513?u=b48c05f669d1ea1d329f90dc70e45f10b569ef55&v=4
|
||||
url: https://github.com/guligon90
|
||||
- login: ybressler
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/40807730?u=6621dc9ab53b697912ab2a32211bb29ae90a9112&v=4
|
||||
url: https://github.com/ybressler
|
||||
- login: iamkarshe
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/43641892?u=d08c901b359c931784501740610d416558ff3e24&v=4
|
||||
url: https://github.com/iamkarshe
|
||||
- login: dbanty
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/43723790?u=0cf33e4f40efc2ea206a1189fd63a11344eb88ed&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/43723790?u=9bcce836bbce55835291c5b2ac93a4e311f4b3c3&v=4
|
||||
url: https://github.com/dbanty
|
||||
- login: rafsaf
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/51059348?u=be9f06b8ced2d2b677297decc781fa8ce4f7ddbd&v=4
|
||||
url: https://github.com/rafsaf
|
||||
- login: dudikbender
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/53487583?u=494f85229115076121b3639a3806bbac1c6ae7f6&v=4
|
||||
url: https://github.com/dudikbender
|
||||
- login: daisuke8000
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/55035595?u=5025e379cd3655ae1a96039efc85223a873d2e38&v=4
|
||||
url: https://github.com/daisuke8000
|
||||
- login: 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: tkrestiankova
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/67013045?v=4
|
||||
url: https://github.com/tkrestiankova
|
||||
- login: around
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/62425723?v=4
|
||||
url: https://github.com/around
|
||||
- login: predictionmachine
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/63719559?v=4
|
||||
url: https://github.com/predictionmachine
|
||||
- login: daverin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/70378377?u=6d1814195c0de7162820eaad95a25b423a3869c0&v=4
|
||||
url: https://github.com/daverin
|
||||
- login: anthonycepeda
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/72019805?u=892f700c79f9732211bd5221bf16eec32356a732&v=4
|
||||
url: https://github.com/anthonycepeda
|
||||
- login: an-tho-ny
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/74874159?v=4
|
||||
url: https://github.com/an-tho-ny
|
||||
- login: NinaHwang
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/79563565?u=1741703bd6c8f491503354b363a86e879b4c1cab&v=4
|
||||
url: https://github.com/NinaHwang
|
||||
- login: dotlas
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/88832003?v=4
|
||||
url: https://github.com/dotlas
|
||||
- login: pyt3h
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/99658549?v=4
|
||||
url: https://github.com/pyt3h
|
||||
- - login: linux-china
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/46711?v=4
|
||||
url: https://github.com/linux-china
|
||||
- login: ddanier
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/113563?v=4
|
||||
url: https://github.com/ddanier
|
||||
- login: jhb
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/142217?v=4
|
||||
url: https://github.com/jhb
|
||||
- login: justinrmiller
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/143998?u=b507a940394d4fc2bc1c27cea2ca9c22538874bd&v=4
|
||||
url: https://github.com/justinrmiller
|
||||
- login: bryanculbertson
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/144028?u=defda4f90e93429221cc667500944abde60ebe4a&v=4
|
||||
url: https://github.com/bryanculbertson
|
||||
- login: yourkin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/178984?v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/178984?u=fa7c3503b47bf16405b96d21554bc59f07a65523&v=4
|
||||
url: https://github.com/yourkin
|
||||
- login: jmagnusson
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/190835?v=4
|
||||
url: https://github.com/jmagnusson
|
||||
- login: sakti
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/196178?u=0110be74c4270244546f1b610334042cd16bb8ad&v=4
|
||||
url: https://github.com/sakti
|
||||
- login: slafs
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/210173?v=4
|
||||
url: https://github.com/slafs
|
||||
- login: assem-ch
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/315228?u=e0c5ab30726d3243a40974bb9bae327866e42d9b&v=4
|
||||
url: https://github.com/assem-ch
|
||||
- login: adamghill
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/317045?u=f1349d5ffe84a19f324e204777859fbf69ddf633&v=4
|
||||
url: https://github.com/adamghill
|
||||
@@ -245,21 +335,33 @@ sponsors:
|
||||
- login: dmig
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/388564?v=4
|
||||
url: https://github.com/dmig
|
||||
- login: hongqn
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/405587?u=470b4c04832e45141fd5264d3354845cc9fc6466&v=4
|
||||
url: https://github.com/hongqn
|
||||
- login: rinckd
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/546002?u=1fcc7e664dc86524a0af6837a0c222829c3fd4e5&v=4
|
||||
url: https://github.com/rinckd
|
||||
- login: securancy
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/606673?v=4
|
||||
url: https://github.com/securancy
|
||||
- login: falkben
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/653031?u=0c8d8f33d87f1aa1a6488d3f02105e9abc838105&v=4
|
||||
url: https://github.com/falkben
|
||||
- login: hardbyte
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/855189?u=aa29e92f34708814d6b67fcd47ca4cf2ce1c04ed&v=4
|
||||
url: https://github.com/hardbyte
|
||||
- login: janfilips
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/870699?u=6034d81731ecb41ae5c717e56a901ed46fc039a8&v=4
|
||||
url: https://github.com/janfilips
|
||||
- login: scari
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/964251?v=4
|
||||
url: https://github.com/scari
|
||||
- login: Pytlicek
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1430522?u=169dba3bfbc04ed214a914640ff435969f19ddb3&v=4
|
||||
url: https://github.com/Pytlicek
|
||||
- login: okken
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1568356?u=0a991a21bdc62e2bea9ad311652f2c45f453dc84&v=4
|
||||
url: https://github.com/okken
|
||||
- login: Celeborn2BeAlive
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1659465?u=944517e4db0f6df65070074e81cabdad9c8a434b&v=4
|
||||
url: https://github.com/Celeborn2BeAlive
|
||||
- login: WillHogan
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1661551?u=7036c064cf29781470573865264ec8e60b6b809f&v=4
|
||||
url: https://github.com/WillHogan
|
||||
- login: cbonoz
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2351087?u=fd3e8030b2cc9fbfbb54a65e9890c548a016f58b&v=4
|
||||
url: https://github.com/cbonoz
|
||||
@@ -269,47 +371,47 @@ sponsors:
|
||||
- login: rglsk
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2768101?u=e349c88673f2155fe021331377c656a9d74bcc25&v=4
|
||||
url: https://github.com/rglsk
|
||||
- login: Atem18
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2875254?v=4
|
||||
url: https://github.com/Atem18
|
||||
- login: paul121
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3116995?u=6e2d8691cc345e63ee02e4eb4d7cef82b1fcbedc&v=4
|
||||
url: https://github.com/paul121
|
||||
- login: igorcorrea
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3438238?u=c57605077c31a8f7b2341fc4912507f91b4a5621&v=4
|
||||
url: https://github.com/igorcorrea
|
||||
- login: anthcor
|
||||
- login: anthonycorletti
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3477132?v=4
|
||||
url: https://github.com/anthcor
|
||||
- login: zsinx6
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3532625?u=ba75a5dc744d1116ccfeaaf30d41cb2fe81fe8dd&v=4
|
||||
url: https://github.com/zsinx6
|
||||
url: https://github.com/anthonycorletti
|
||||
- login: pawamoy
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3999221?u=b030e4c89df2f3a36bc4710b925bdeb6745c9856&v=4
|
||||
url: https://github.com/pawamoy
|
||||
- login: spyker77
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4953435?u=03c724c6f8fbab5cd6575b810c0c91c652fa4f79&v=4
|
||||
url: https://github.com/spyker77
|
||||
- login: JonasKs
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5310116?u=98a049f3e1491bffb91e1feb7e93def6881a9389&v=4
|
||||
url: https://github.com/JonasKs
|
||||
- login: Alisa-lisa
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4137964?u=e7e393504f554f4ff15863a1e01a5746863ef9ce&v=4
|
||||
url: https://github.com/Alisa-lisa
|
||||
- login: unredundant
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5607577?u=57dd0023365bec03f4fc566df6b81bc0a264a47d&v=4
|
||||
url: https://github.com/unredundant
|
||||
- login: holec
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6438041?u=f5af71ec85b3a9d7b8139cb5af0512b02fa9ab1e&v=4
|
||||
url: https://github.com/holec
|
||||
- login: BartlomiejRasztabiga
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8852711?u=ed213d60f7a423df31ceb1004aa3ec60e612cb98&v=4
|
||||
url: https://github.com/BartlomiejRasztabiga
|
||||
- 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: and-semakin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9129071?u=ea77ddf7de4bc375d546bf2825ed420eaddb7666&v=4
|
||||
url: https://github.com/and-semakin
|
||||
- login: yenchenLiu
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9199638?u=8cdf5ae507448430d90f6f3518d1665a23afe99b&v=4
|
||||
url: https://github.com/yenchenLiu
|
||||
- login: VivianSolide
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9358572?u=ffb2e2ec522a15dcd3f0af1f9fd1df4afe418afa&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9358572?u=4a38ef72dd39e8b262bd5ab819992128b55c52b4&v=4
|
||||
url: https://github.com/VivianSolide
|
||||
- login: xncbf
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9462045?u=866a1311e4bd3ec5ae84185c4fcc99f397c883d7&v=4
|
||||
url: https://github.com/xncbf
|
||||
- login: DMantis
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9536869?v=4
|
||||
url: https://github.com/DMantis
|
||||
- login: hard-coders
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=f2d3d2038c55d86d7f9348f4e6c5e30191e4ee8b&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
|
||||
url: https://github.com/hard-coders
|
||||
- login: satwikkansal
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10217535?u=b12d6ef74ea297de9e46da6933b1a5b7ba9e6a61&v=4
|
||||
@@ -317,63 +419,78 @@ sponsors:
|
||||
- login: pheanex
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10408624?u=5b6bab6ee174aa6e991333e06eb29f628741013d&v=4
|
||||
url: https://github.com/pheanex
|
||||
- login: wotori
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10486621?u=0044c295b91694b8c9bccc0a805681f794250f7b&v=4
|
||||
url: https://github.com/wotori
|
||||
- login: JimFawkes
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/12075115?u=dc58ecfd064d72887c34bf500ddfd52592509acd&v=4
|
||||
url: https://github.com/JimFawkes
|
||||
- login: logan-connolly
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16244943?u=8ae66dfbba936463cc8aa0dd7a6d2b4c0cc757eb&v=4
|
||||
url: https://github.com/logan-connolly
|
||||
- login: iPr0ger
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/19322290?v=4
|
||||
url: https://github.com/iPr0ger
|
||||
- login: cdsre
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16945936?v=4
|
||||
url: https://github.com/cdsre
|
||||
- login: jangia
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/17927101?u=9261b9bb0c3e3bb1ecba43e8915dc58d8c9a077e&v=4
|
||||
url: https://github.com/jangia
|
||||
- login: ghandic
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/23500353?u=e2e1d736f924d9be81e8bfc565b6d8836ba99773&v=4
|
||||
url: https://github.com/ghandic
|
||||
- login: MoronVV
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/24293616?v=4
|
||||
url: https://github.com/MoronVV
|
||||
- login: fstau
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/24669867?u=60e7c8c09f8dafabee8fc3edcd6f9e19abbff918&v=4
|
||||
url: https://github.com/fstau
|
||||
- login: mertguvencli
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/29762151?u=16a906d90df96c8cff9ea131a575c4bc171b1523&v=4
|
||||
url: https://github.com/mertguvencli
|
||||
- login: rgreen32
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/35779241?u=c9d64ad1ab364b6a1ec8e3d859da9ca802d681d8&v=4
|
||||
url: https://github.com/rgreen32
|
||||
- login: askurihin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/37978981?v=4
|
||||
url: https://github.com/askurihin
|
||||
- login: JitPackJoyride
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/40203625?u=9638bfeacfa5940358188f8205ce662bba022b53&v=4
|
||||
url: https://github.com/JitPackJoyride
|
||||
- login: es3n1n
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/40367813?u=e881a3880f1e342d19a1ea7c8e1b6d76c52dc294&v=4
|
||||
url: https://github.com/es3n1n
|
||||
- login: dwreeves
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31971762?u=69732aba05aa5cf0780866349ebe109cf632b047&v=4
|
||||
url: https://github.com/dwreeves
|
||||
- login: kitaramu0401
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/33246506?u=929e6efa2c518033b8097ba524eb5347a069bb3b&v=4
|
||||
url: https://github.com/kitaramu0401
|
||||
- login: engineerjoe440
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/33275230?u=eb223cad27017bb1e936ee9b429b450d092d0236&v=4
|
||||
url: https://github.com/engineerjoe440
|
||||
- login: declon
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/36180226?v=4
|
||||
url: https://github.com/declon
|
||||
- login: d-e-h-i-o
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/36816716?v=4
|
||||
url: https://github.com/d-e-h-i-o
|
||||
- login: ilias-ant
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/42189572?u=a2d6121bac4d125d92ec207460fa3f1842d37e66&v=4
|
||||
url: https://github.com/ilias-ant
|
||||
- login: arrrrrmin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/43553423?u=05600727f1cfe75f440bb3fddd49bfea84b1e894&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/43553423?u=fee5739394fea074cb0b66929d070114a5067aae&v=4
|
||||
url: https://github.com/arrrrrmin
|
||||
- login: Nephilim-Jack
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/48372168?u=6f2bb405238d7efc467536fe01f58df6779c58a9&v=4
|
||||
url: https://github.com/Nephilim-Jack
|
||||
- login: akanz1
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/51492342?u=2280f57134118714645e16b535c1a37adf6b369b&v=4
|
||||
url: https://github.com/akanz1
|
||||
- - login: leogregianin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1684053?u=94ddd387601bd1805034dbe83e6eba0491c15323&v=4
|
||||
url: https://github.com/leogregianin
|
||||
- login: rooflexx
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/58993673?u=f8ba450460f1aea18430ed1e4a3889049a3b4dfa&v=4
|
||||
url: https://github.com/rooflexx
|
||||
- login: denisyao1
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/60019356?v=4
|
||||
url: https://github.com/denisyao1
|
||||
- login: apar-tiwari
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/61064197?v=4
|
||||
url: https://github.com/apar-tiwari
|
||||
- login: 0417taehyun
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/63915557?u=47debaa860fd52c9b98c97ef357ddcec3b3fb399&v=4
|
||||
url: https://github.com/0417taehyun
|
||||
- login: alessio-proietti
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/67370599?u=8ac73db1e18e946a7681f173abdb640516f88515&v=4
|
||||
url: https://github.com/alessio-proietti
|
||||
- - login: backbord
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6814946?v=4
|
||||
url: https://github.com/backbord
|
||||
- login: sadikkuzu
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/23168063?u=765ed469c44c004560079210ccdad5b29938eaa9&v=4
|
||||
url: https://github.com/sadikkuzu
|
||||
- login: gabrielmbmb
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/29572918?u=92084ed7242160dee4d20aece923a10c59758ee5&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/29572918?u=6d1e00b5d558e96718312ff910a2318f47cc3145&v=4
|
||||
url: https://github.com/gabrielmbmb
|
||||
- login: starhype
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/36908028?u=6df41f7b62f0f673f1ecbc87e9cbadaa4fcb0767&v=4
|
||||
url: https://github.com/starhype
|
||||
- login: pixel365
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/53819609?u=9e0309c5420ec4624aececd3ca2d7105f7f68133&v=4
|
||||
url: https://github.com/pixel365
|
||||
- login: danburonline
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/34251194?u=2cad4388c1544e539ecb732d656e42fb07b4ff2d&v=4
|
||||
url: https://github.com/danburonline
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
maintainers:
|
||||
- login: tiangolo
|
||||
answers: 1230
|
||||
prs: 269
|
||||
answers: 1243
|
||||
prs: 300
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=5cad72c846b7aba2e960546af490edc7375dafc4&v=4
|
||||
url: https://github.com/tiangolo
|
||||
experts:
|
||||
- login: Kludex
|
||||
count: 315
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=cf8455cb899806b774a3a71073f88583adec99f6&v=4
|
||||
count: 335
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
|
||||
url: https://github.com/Kludex
|
||||
- login: dmontagu
|
||||
count: 262
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=58ed2a45798a4339700e2f62b2e12e6e54bf0396&v=4
|
||||
url: https://github.com/dmontagu
|
||||
- login: ycd
|
||||
count: 219
|
||||
count: 221
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=826f228edf0bab0d19ad1d5c4ba4df1047ccffef&v=4
|
||||
url: https://github.com/ycd
|
||||
- login: Mause
|
||||
@@ -29,14 +29,14 @@ experts:
|
||||
count: 130
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/331403?v=4
|
||||
url: https://github.com/phy25
|
||||
- login: ArcLightSlavik
|
||||
count: 71
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=81a84af39c89b898b0fbc5a04e8834f60f23e55a&v=4
|
||||
url: https://github.com/ArcLightSlavik
|
||||
- login: raphaelauv
|
||||
count: 63
|
||||
count: 71
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
|
||||
url: https://github.com/raphaelauv
|
||||
- login: ArcLightSlavik
|
||||
count: 71
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=b0f2c37142f4b762e41ad65dc49581813422bd71&v=4
|
||||
url: https://github.com/ArcLightSlavik
|
||||
- login: falkben
|
||||
count: 58
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/653031?u=0c8d8f33d87f1aa1a6488d3f02105e9abc838105&v=4
|
||||
@@ -45,26 +45,38 @@ experts:
|
||||
count: 48
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/516999?u=437c0c5038558c67e887ccd863c1ba0f846c03da&v=4
|
||||
url: https://github.com/sm-Fifteen
|
||||
- login: insomnes
|
||||
count: 46
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16958893?u=f8be7088d5076d963984a21f95f44e559192d912&v=4
|
||||
url: https://github.com/insomnes
|
||||
- login: Dustyposa
|
||||
count: 42
|
||||
count: 43
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4
|
||||
url: https://github.com/Dustyposa
|
||||
- login: includeamin
|
||||
count: 38
|
||||
count: 39
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11836741?u=8bd5ef7e62fe6a82055e33c4c0e0a7879ff8cfb6&v=4
|
||||
url: https://github.com/includeamin
|
||||
- login: insomnes
|
||||
- login: jgould22
|
||||
count: 38
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
|
||||
url: https://github.com/jgould22
|
||||
- login: STeveShary
|
||||
count: 37
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16958893?u=f8be7088d5076d963984a21f95f44e559192d912&v=4
|
||||
url: https://github.com/insomnes
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5167622?u=de8f597c81d6336fcebc37b32dfd61a3f877160c&v=4
|
||||
url: https://github.com/STeveShary
|
||||
- login: adriangb
|
||||
count: 36
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1755071?u=81f0262df34e1460ca546fbd0c211169c2478532&v=4
|
||||
url: https://github.com/adriangb
|
||||
- login: prostomarkeloff
|
||||
count: 33
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/28061158?u=72309cc1f2e04e40fa38b29969cb4e9d3f722e7b&v=4
|
||||
url: https://github.com/prostomarkeloff
|
||||
- login: STeveShary
|
||||
count: 32
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5167622?u=de8f597c81d6336fcebc37b32dfd61a3f877160c&v=4
|
||||
url: https://github.com/STeveShary
|
||||
- login: frankie567
|
||||
count: 31
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1144727?u=85c025e3fcc7bd79a5665c63ee87cdf8aae13374&v=4
|
||||
url: https://github.com/frankie567
|
||||
- login: krishnardt
|
||||
count: 31
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31960541?u=47f4829c77f4962ab437ffb7995951e41eeebe9b&v=4
|
||||
@@ -73,14 +85,14 @@ experts:
|
||||
count: 29
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
|
||||
url: https://github.com/wshayes
|
||||
- login: frankie567
|
||||
count: 29
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1144727?u=85c025e3fcc7bd79a5665c63ee87cdf8aae13374&v=4
|
||||
url: https://github.com/frankie567
|
||||
- login: adriangb
|
||||
- login: chbndrhnns
|
||||
count: 28
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7534547?v=4
|
||||
url: https://github.com/chbndrhnns
|
||||
- login: panla
|
||||
count: 26
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1755071?u=81f0262df34e1460ca546fbd0c211169c2478532&v=4
|
||||
url: https://github.com/adriangb
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/41326348?u=ba2fda6b30110411ecbf406d187907e2b420ac19&v=4
|
||||
url: https://github.com/panla
|
||||
- login: ghandic
|
||||
count: 25
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/23500353?u=e2e1d736f924d9be81e8bfc565b6d8836ba99773&v=4
|
||||
@@ -89,10 +101,6 @@ experts:
|
||||
count: 25
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/43723790?u=9bcce836bbce55835291c5b2ac93a4e311f4b3c3&v=4
|
||||
url: https://github.com/dbanty
|
||||
- login: chbndrhnns
|
||||
count: 24
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7534547?v=4
|
||||
url: https://github.com/chbndrhnns
|
||||
- login: SirTelemak
|
||||
count: 24
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9435877?u=719327b7d2c4c62212456d771bfa7c6b8dbb9eac&v=4
|
||||
@@ -109,14 +117,14 @@ experts:
|
||||
count: 21
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/565544?v=4
|
||||
url: https://github.com/chris-allnutt
|
||||
- login: panla
|
||||
count: 21
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/41326348?u=ba2fda6b30110411ecbf406d187907e2b420ac19&v=4
|
||||
url: https://github.com/panla
|
||||
- login: retnikt
|
||||
count: 19
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/24581770?v=4
|
||||
url: https://github.com/retnikt
|
||||
- login: acidjunk
|
||||
count: 18
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
|
||||
url: https://github.com/acidjunk
|
||||
- login: Hultner
|
||||
count: 18
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2669034?u=115e53df959309898ad8dc9443fbb35fee71df07&v=4
|
||||
@@ -129,26 +137,46 @@ experts:
|
||||
count: 17
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/28262306?u=66ee21316275ef356081c2efc4ed7a4572e690dc&v=4
|
||||
url: https://github.com/nkhitrov
|
||||
- login: harunyasar
|
||||
count: 17
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1765494?u=5b1ab7c582db4b4016fa31affe977d10af108ad4&v=4
|
||||
url: https://github.com/harunyasar
|
||||
- login: rafsaf
|
||||
count: 17
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/51059348?u=be9f06b8ced2d2b677297decc781fa8ce4f7ddbd&v=4
|
||||
url: https://github.com/rafsaf
|
||||
- login: waynerv
|
||||
count: 16
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
|
||||
url: https://github.com/waynerv
|
||||
- login: acidjunk
|
||||
count: 15
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
|
||||
url: https://github.com/acidjunk
|
||||
- login: dstlny
|
||||
count: 16
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/41964673?u=9f2174f9d61c15c6e3a4c9e3aeee66f711ce311f&v=4
|
||||
url: https://github.com/dstlny
|
||||
- login: haizaar
|
||||
count: 13
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/58201?u=4f1f9843d69433ca0d380d95146cfe119e5fdac4&v=4
|
||||
url: https://github.com/haizaar
|
||||
- login: dstlny
|
||||
- login: valentin994
|
||||
count: 13
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/41964673?u=9f2174f9d61c15c6e3a4c9e3aeee66f711ce311f&v=4
|
||||
url: https://github.com/dstlny
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/42819267?u=fdeeaa9242a59b243f8603496b00994f6951d5a2&v=4
|
||||
url: https://github.com/valentin994
|
||||
- login: hellocoldworld
|
||||
count: 12
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/47581948?v=4
|
||||
url: https://github.com/hellocoldworld
|
||||
- login: David-Lor
|
||||
count: 12
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/17401854?u=474680c02b94cba810cb9032fb7eb787d9cc9d22&v=4
|
||||
url: https://github.com/David-Lor
|
||||
- login: yinziyan1206
|
||||
count: 12
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/37829370?v=4
|
||||
url: https://github.com/yinziyan1206
|
||||
- login: jonatasoli
|
||||
count: 12
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/26334101?u=071c062d2861d3dd127f6b4a5258cd8ef55d4c50&v=4
|
||||
url: https://github.com/jonatasoli
|
||||
- login: lowercase00
|
||||
count: 11
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/21188280?v=4
|
||||
@@ -161,43 +189,35 @@ experts:
|
||||
count: 11
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8134632?v=4
|
||||
url: https://github.com/juntatalor
|
||||
- login: valentin994
|
||||
- login: n8sty
|
||||
count: 11
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/42819267?u=fdeeaa9242a59b243f8603496b00994f6951d5a2&v=4
|
||||
url: https://github.com/valentin994
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2964996?v=4
|
||||
url: https://github.com/n8sty
|
||||
- login: aalifadv
|
||||
count: 11
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/78442260?v=4
|
||||
url: https://github.com/aalifadv
|
||||
- login: stefanondisponibile
|
||||
count: 10
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/20441825?u=ee1e59446b98f8ec2363caeda4c17164d0d9cc7d&v=4
|
||||
url: https://github.com/stefanondisponibile
|
||||
- login: hellocoldworld
|
||||
count: 10
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/47581948?v=4
|
||||
url: https://github.com/hellocoldworld
|
||||
- login: oligond
|
||||
count: 10
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2858306?u=1bb1182a5944e93624b7fb26585f22c8f7a9d76e&v=4
|
||||
url: https://github.com/oligond
|
||||
last_month_active:
|
||||
- login: raphaelauv
|
||||
count: 6
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
|
||||
url: https://github.com/raphaelauv
|
||||
- login: oligond
|
||||
- login: jgould22
|
||||
count: 15
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
|
||||
url: https://github.com/jgould22
|
||||
- login: accelleon
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2858306?u=1bb1182a5944e93624b7fb26585f22c8f7a9d76e&v=4
|
||||
url: https://github.com/oligond
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5001614?v=4
|
||||
url: https://github.com/accelleon
|
||||
- login: jonatasoli
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/26334101?u=071c062d2861d3dd127f6b4a5258cd8ef55d4c50&v=4
|
||||
url: https://github.com/jonatasoli
|
||||
- login: Kludex
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=cf8455cb899806b774a3a71073f88583adec99f6&v=4
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
|
||||
url: https://github.com/Kludex
|
||||
- login: Dustyposa
|
||||
- login: yinziyan1206
|
||||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4
|
||||
url: https://github.com/Dustyposa
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/37829370?v=4
|
||||
url: https://github.com/yinziyan1206
|
||||
top_contributors:
|
||||
- login: waynerv
|
||||
count: 25
|
||||
@@ -211,14 +231,14 @@ top_contributors:
|
||||
count: 16
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=58ed2a45798a4339700e2f62b2e12e6e54bf0396&v=4
|
||||
url: https://github.com/dmontagu
|
||||
- login: jaystone776
|
||||
count: 15
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11191137?u=299205a95e9b6817a43144a48b643346a5aac5cc&v=4
|
||||
url: https://github.com/jaystone776
|
||||
- login: euri10
|
||||
count: 13
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1104190?u=321a2e953e6645a7d09b732786c7a8061e0f8a8b&v=4
|
||||
url: https://github.com/euri10
|
||||
- login: jaystone776
|
||||
count: 13
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11191137?u=299205a95e9b6817a43144a48b643346a5aac5cc&v=4
|
||||
url: https://github.com/jaystone776
|
||||
- login: mariacamilagl
|
||||
count: 12
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11489395?u=4adb6986bf3debfc2b8216ae701f2bd47d73da7d&v=4
|
||||
@@ -231,14 +251,14 @@ top_contributors:
|
||||
count: 8
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/22691749?u=4795b880e13ca33a73e52fc0ef7dc9c60c8fce47&v=4
|
||||
url: https://github.com/Serrones
|
||||
- login: Kludex
|
||||
count: 8
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
|
||||
url: https://github.com/Kludex
|
||||
- login: RunningIkkyu
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31848542?u=706e1ee3f248245f2d68b976d149d06fd5a2010d&v=4
|
||||
url: https://github.com/RunningIkkyu
|
||||
- login: Kludex
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=cf8455cb899806b774a3a71073f88583adec99f6&v=4
|
||||
url: https://github.com/Kludex
|
||||
- login: hard-coders
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
|
||||
@@ -273,12 +293,12 @@ top_contributors:
|
||||
url: https://github.com/komtaki
|
||||
- login: NinaHwang
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/79563565?u=36ca24be1fc3daa967b0f409bab0e17132d8c80c&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/79563565?u=1741703bd6c8f491503354b363a86e879b4c1cab&v=4
|
||||
url: https://github.com/NinaHwang
|
||||
top_reviewers:
|
||||
- login: Kludex
|
||||
count: 91
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=cf8455cb899806b774a3a71073f88583adec99f6&v=4
|
||||
count: 93
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
|
||||
url: https://github.com/Kludex
|
||||
- login: waynerv
|
||||
count: 47
|
||||
@@ -293,29 +313,41 @@ top_reviewers:
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/41147016?u=55010621aece725aa702270b54fed829b6a1fe60&v=4
|
||||
url: https://github.com/tokusumi
|
||||
- login: ycd
|
||||
count: 44
|
||||
count: 45
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=826f228edf0bab0d19ad1d5c4ba4df1047ccffef&v=4
|
||||
url: https://github.com/ycd
|
||||
- login: cikay
|
||||
count: 41
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/24587499?u=e772190a051ab0eaa9c8542fcff1892471638f2b&v=4
|
||||
url: https://github.com/cikay
|
||||
- login: BilalAlpaslan
|
||||
count: 40
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/47563997?u=63ed66e304fe8d765762c70587d61d9196e5c82d&v=4
|
||||
url: https://github.com/BilalAlpaslan
|
||||
- login: AdrianDeAnda
|
||||
count: 33
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1024932?u=bb7f8a0d6c9de4e9d0320a9f271210206e202250&v=4
|
||||
url: https://github.com/AdrianDeAnda
|
||||
- login: ArcLightSlavik
|
||||
count: 31
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=81a84af39c89b898b0fbc5a04e8834f60f23e55a&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=b0f2c37142f4b762e41ad65dc49581813422bd71&v=4
|
||||
url: https://github.com/ArcLightSlavik
|
||||
- login: cassiobotaro
|
||||
count: 25
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3127847?u=b0a652331da17efeb85cd6e3a4969182e5004804&v=4
|
||||
url: https://github.com/cassiobotaro
|
||||
- login: dmontagu
|
||||
count: 23
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=58ed2a45798a4339700e2f62b2e12e6e54bf0396&v=4
|
||||
url: https://github.com/dmontagu
|
||||
- login: cassiobotaro
|
||||
count: 22
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3127847?u=b0a652331da17efeb85cd6e3a4969182e5004804&v=4
|
||||
url: https://github.com/cassiobotaro
|
||||
- login: komtaki
|
||||
count: 21
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/39375566?u=260ad6b1a4b34c07dbfa728da5e586f16f6d1824&v=4
|
||||
url: https://github.com/komtaki
|
||||
- login: yezz123
|
||||
count: 19
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/52716203?u=636b4f79645176df4527dd45c12d5dbb5a4193cf&v=4
|
||||
url: https://github.com/yezz123
|
||||
- login: hard-coders
|
||||
count: 19
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
|
||||
@@ -324,10 +356,18 @@ top_reviewers:
|
||||
count: 19
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/63915557?u=47debaa860fd52c9b98c97ef357ddcec3b3fb399&v=4
|
||||
url: https://github.com/0417taehyun
|
||||
- login: zy7y
|
||||
count: 17
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/67154681?u=5d634834cc514028ea3f9115f7030b99a1f4d5a4&v=4
|
||||
url: https://github.com/zy7y
|
||||
- login: yanever
|
||||
count: 16
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/21978760?v=4
|
||||
url: https://github.com/yanever
|
||||
- login: lsglucas
|
||||
count: 16
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/61513630?u=320e43fe4dc7bc6efc64e9b8f325f8075634fd20&v=4
|
||||
url: https://github.com/lsglucas
|
||||
- login: SwftAlpc
|
||||
count: 16
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/52768429?u=6a3aa15277406520ad37f6236e89466ed44bc5b8&v=4
|
||||
@@ -348,12 +388,8 @@ top_reviewers:
|
||||
count: 15
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/63476957?u=6c86e59b48e0394d4db230f37fc9ad4d7e2c27c7&v=4
|
||||
url: https://github.com/delhi09
|
||||
- login: lsglucas
|
||||
count: 14
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/61513630?u=320e43fe4dc7bc6efc64e9b8f325f8075634fd20&v=4
|
||||
url: https://github.com/lsglucas
|
||||
- login: rjNemo
|
||||
count: 13
|
||||
count: 14
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/56785022?u=d5c3a02567c8649e146fcfc51b6060ccaf8adef8&v=4
|
||||
url: https://github.com/rjNemo
|
||||
- login: RunningIkkyu
|
||||
@@ -376,10 +412,10 @@ top_reviewers:
|
||||
count: 10
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7887703?v=4
|
||||
url: https://github.com/maoyibo
|
||||
- login: yezz123
|
||||
count: 9
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/52716203?u=636b4f79645176df4527dd45c12d5dbb5a4193cf&v=4
|
||||
url: https://github.com/yezz123
|
||||
- login: solomein-sv
|
||||
count: 10
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/46193920?u=46acfb4aeefb1d7b9fdc5a8cbd9eb8744683c47a&v=4
|
||||
url: https://github.com/solomein-sv
|
||||
- login: graingert
|
||||
count: 9
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/413772?v=4
|
||||
@@ -396,18 +432,26 @@ top_reviewers:
|
||||
count: 9
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/69092910?u=4ac58eab99bd37d663f3d23551df96d4fbdbf760&v=4
|
||||
url: https://github.com/bezaca
|
||||
- login: solomein-sv
|
||||
count: 9
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/46193920?u=46acfb4aeefb1d7b9fdc5a8cbd9eb8744683c47a&v=4
|
||||
url: https://github.com/solomein-sv
|
||||
- login: blt232018
|
||||
count: 8
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/43393471?u=172b0e0391db1aa6c1706498d6dfcb003c8a4857&v=4
|
||||
url: https://github.com/blt232018
|
||||
- login: rogerbrinkmann
|
||||
count: 8
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5690226?v=4
|
||||
url: https://github.com/rogerbrinkmann
|
||||
- login: ComicShrimp
|
||||
count: 8
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/43503750?u=b3e4d9a14d9a65d429ce62c566aef73178b7111d&v=4
|
||||
url: https://github.com/ComicShrimp
|
||||
- login: NinaHwang
|
||||
count: 8
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/79563565?u=1741703bd6c8f491503354b363a86e879b4c1cab&v=4
|
||||
url: https://github.com/NinaHwang
|
||||
- login: dimaqq
|
||||
count: 8
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/662249?v=4
|
||||
url: https://github.com/dimaqq
|
||||
- login: Serrones
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/22691749?u=4795b880e13ca33a73e52fc0ef7dc9c60c8fce47&v=4
|
||||
@@ -428,6 +472,10 @@ top_reviewers:
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1405026?v=4
|
||||
url: https://github.com/Mause
|
||||
- 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
|
||||
@@ -436,39 +484,11 @@ top_reviewers:
|
||||
count: 6
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/21287303?u=b049eac3e51a4c0473c2efe66b4d28a7d8f2b572&v=4
|
||||
url: https://github.com/jovicon
|
||||
- login: BilalAlpaslan
|
||||
- login: LorhanSohaky
|
||||
count: 6
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/47563997?u=63ed66e304fe8d765762c70587d61d9196e5c82d&v=4
|
||||
url: https://github.com/BilalAlpaslan
|
||||
- login: diogoduartec
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31852339?u=b50fc11c531e9b77922e19edfc9e7233d4d7b92e&v=4
|
||||
url: https://github.com/diogoduartec
|
||||
- login: nimctl
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/49960770?u=e39b11d47188744ee07b2a1c7ce1a1bdf3c80760&v=4
|
||||
url: https://github.com/nimctl
|
||||
- login: juntatalor
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8134632?v=4
|
||||
url: https://github.com/juntatalor
|
||||
- login: SnkSynthesis
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/63564282?u=0078826509dbecb2fdb543f4e881c9cd06157893&v=4
|
||||
url: https://github.com/SnkSynthesis
|
||||
- login: anthonycepeda
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/72019805?u=892f700c79f9732211bd5221bf16eec32356a732&v=4
|
||||
url: https://github.com/anthonycepeda
|
||||
- login: oandersonmagalhaes
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/83456692?v=4
|
||||
url: https://github.com/oandersonmagalhaes
|
||||
- login: euri10
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1104190?u=321a2e953e6645a7d09b732786c7a8061e0f8a8b&v=4
|
||||
url: https://github.com/euri10
|
||||
- login: rkbeatss
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/23391143?u=56ab6bff50be950fa8cae5cf736f2ae66e319ff3&v=4
|
||||
url: https://github.com/rkbeatss
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16273730?u=095b66f243a2cd6a0aadba9a095009f8aaf18393&v=4
|
||||
url: https://github.com/LorhanSohaky
|
||||
- login: peidrao
|
||||
count: 6
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/32584628?u=88c2cb42a99e0f50cdeae3606992568184783ee5&v=4
|
||||
url: https://github.com/peidrao
|
||||
|
||||
@@ -5,6 +5,12 @@ gold:
|
||||
- url: https://cryptapi.io/
|
||||
title: "CryptAPI: Your easy to use, secure and privacy oriented payment gateway."
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/cryptapi.svg
|
||||
- url: https://classiq.link/n4s
|
||||
title: Join the team building a new SaaS platform that will change the computing world
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/classiq.png
|
||||
- url: https://www.dropbase.io/careers
|
||||
title: Dropbase - seamlessly collect, clean, and centralize data.
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/dropbase.svg
|
||||
silver:
|
||||
- url: https://www.deta.sh/?ref=fastapi
|
||||
title: The launchpad for all your (team's) ideas
|
||||
@@ -12,10 +18,7 @@ silver:
|
||||
- url: https://www.investsuite.com/jobs
|
||||
title: Wealthtech jobs with FastAPI
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/investsuite.svg
|
||||
- url: https://www.vim.so/?utm_source=FastAPI
|
||||
title: We help you master vim with interactive exercises
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/vimso.png
|
||||
- url: https://talkpython.fm/fastapi-sponsor
|
||||
- url: https://training.talkpython.fm/fastapi-courses
|
||||
title: FastAPI video courses on demand from people you trust
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/talkpython.png
|
||||
- url: https://testdriven.io/courses/tdd-fastapi/
|
||||
@@ -24,7 +27,16 @@ silver:
|
||||
- url: https://github.com/deepset-ai/haystack/
|
||||
title: Build powerful search from composable, open source building blocks
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/haystack-fastapi.svg
|
||||
- url: https://www.udemy.com/course/fastapi-rest/
|
||||
title: Learn FastAPI by building a complete project. Extend your knowledge on advanced web development-AWS, Payments, Emails.
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/ines-course.jpg
|
||||
- url: https://careers.budget-insight.com/
|
||||
title: Budget Insight is hiring!
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/budget-insight.svg
|
||||
bronze:
|
||||
- url: https://calmcode.io
|
||||
title: Code. Simply. Clearly. Calmly.
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/calmcode.jpg
|
||||
- url: https://www.exoflare.com/open-source/?utm_source=FastAPI&utm_campaign=open_source
|
||||
title: Biosecurity risk assessments made easy.
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/exoflare.png
|
||||
- url: https://striveworks.us/careers?utm_source=fastapi&utm_medium=sponsor_banner&utm_campaign=feb_march#openings
|
||||
title: https://striveworks.us/careers
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/striveworks.png
|
||||
|
||||
@@ -2,8 +2,11 @@ logins:
|
||||
- jina-ai
|
||||
- deta
|
||||
- investsuite
|
||||
- vimsoHQ
|
||||
- mikeckennedy
|
||||
- koaning
|
||||
- deepset-ai
|
||||
- cryptapi
|
||||
- Striveworks
|
||||
- xoflare
|
||||
- InesIvanova
|
||||
- DropbaseHQ
|
||||
- VincentParedes
|
||||
|
||||
@@ -233,3 +233,82 @@ Now, to be able to test that everything works, create a *path operation*:
|
||||
Now, you should be able to disconnect your WiFi, go to your docs at <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>, and reload the page.
|
||||
|
||||
And even without Internet, you would be able to see the docs for your API and interact with it.
|
||||
|
||||
## Configuring Swagger UI
|
||||
|
||||
You can configure some extra <a href="https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration" class="external-link" target="_blank">Swagger UI parameters</a>.
|
||||
|
||||
To configure them, pass the `swagger_ui_parameters` argument when creating the `FastAPI()` app object or to the `get_swagger_ui_html()` function.
|
||||
|
||||
`swagger_ui_parameters` receives a dictionary with the configurations passed to Swagger UI directly.
|
||||
|
||||
FastAPI converts the configurations to **JSON** to make them compatible with JavaScript, as that's what Swagger UI needs.
|
||||
|
||||
### Disable Syntax Highlighting
|
||||
|
||||
For example, you could disable syntax highlighting in Swagger UI.
|
||||
|
||||
Without changing the settings, syntax highlighting is enabled by default:
|
||||
|
||||
<img src="/img/tutorial/extending-openapi/image02.png">
|
||||
|
||||
But you can disable it by setting `syntaxHighlight` to `False`:
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!../../../docs_src/extending_openapi/tutorial003.py!}
|
||||
```
|
||||
|
||||
...and then Swagger UI won't show the syntax highlighting anymore:
|
||||
|
||||
<img src="/img/tutorial/extending-openapi/image03.png">
|
||||
|
||||
### Change the Theme
|
||||
|
||||
The same way you could set the syntax highlighting theme with the key `"syntaxHighlight.theme"` (notice that it has a dot in the middle):
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!../../../docs_src/extending_openapi/tutorial004.py!}
|
||||
```
|
||||
|
||||
That configuration would change the syntax highlighting color theme:
|
||||
|
||||
<img src="/img/tutorial/extending-openapi/image04.png">
|
||||
|
||||
### Change Default Swagger UI Parameters
|
||||
|
||||
FastAPI includes some default configuration parameters appropriate for most of the use cases.
|
||||
|
||||
It includes these default configurations:
|
||||
|
||||
```Python
|
||||
{!../../../fastapi/openapi/docs.py[ln:7-13]!}
|
||||
```
|
||||
|
||||
You can override any of them by setting a different value in the argument `swagger_ui_parameters`.
|
||||
|
||||
For example, to disable `deepLinking` you could pass these settings to `swagger_ui_parameters`:
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!../../../docs_src/extending_openapi/tutorial005.py!}
|
||||
```
|
||||
|
||||
### Other Swagger UI Parameters
|
||||
|
||||
To see all the other possible configurations you can use, read the official <a href="https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration" class="external-link" target="_blank">docs for Swagger UI parameters</a>.
|
||||
|
||||
### JavaScript-only settings
|
||||
|
||||
Swagger UI also allows other configurations to be **JavaScript-only** objects (for example, JavaScript functions).
|
||||
|
||||
FastAPI also includes these JavaScript-only `presets` settings:
|
||||
|
||||
```JavaScript
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIBundle.SwaggerUIStandalonePreset
|
||||
]
|
||||
```
|
||||
|
||||
These are **JavaScript** objects, not strings, so you can't pass them from Python code directly.
|
||||
|
||||
If you need to use JavaScript-only configurations like those, you can use one of the methods above. Override all the Swagger UI *path operation* and manually write any JavaScript you need.
|
||||
|
||||
267
docs/en/docs/advanced/generate-clients.md
Normal file
@@ -0,0 +1,267 @@
|
||||
# Generate Clients
|
||||
|
||||
As **FastAPI** is based on the OpenAPI specification, you get automatic compatibility with many tools, including the automatic API docs (provided by Swagger UI).
|
||||
|
||||
One particular advantage that is not necessarily obvious is that you can **generate clients** (sometimes called <abbr title="Software Development Kits">**SDKs**</abbr> ) for your API, for many different **programming languages**.
|
||||
|
||||
## OpenAPI Client Generators
|
||||
|
||||
There are many tools to generate clients from **OpenAPI**.
|
||||
|
||||
A common tool is <a href="https://openapi-generator.tech/" class="external-link" target="_blank">OpenAPI Generator</a>.
|
||||
|
||||
If you are building a **frontend**, a very interesting alternative is <a href="https://github.com/ferdikoomen/openapi-typescript-codegen" class="external-link" target="_blank">openapi-typescript-codegen</a>.
|
||||
|
||||
## Generate a TypeScript Frontend Client
|
||||
|
||||
Let's start with a simple FastAPI application:
|
||||
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="9-11 14-15 18 19 23"
|
||||
{!> ../../../docs_src/generate_clients/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="7-9 12-13 16-17 21"
|
||||
{!> ../../../docs_src/generate_clients/tutorial001_py39.py!}
|
||||
```
|
||||
|
||||
Notice that the *path operations* define the models they use for request payload and response payload, using the models `Item` and `ResponseMessage`.
|
||||
|
||||
### API Docs
|
||||
|
||||
If you go to the API docs, you will see that it has the **schemas** for the data to be sent in requests and received in responses:
|
||||
|
||||
<img src="/img/tutorial/generate-clients/image01.png">
|
||||
|
||||
You can see those schemas because they were declared with the models in the app.
|
||||
|
||||
That information is available in the app's **OpenAPI schema**, and then shown in the API docs (by Swagger UI).
|
||||
|
||||
And that same information from the models that is included in OpenAPI is what can be used to **generate the client code**.
|
||||
|
||||
### Generate a TypeScript Client
|
||||
|
||||
Now that we have the app with the models, we can generate the client code for the frontend.
|
||||
|
||||
#### Install `openapi-typescript-codegen`
|
||||
|
||||
You can install `openapi-typescript-codegen` in your frontend code with:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ npm install openapi-typescript-codegen --save-dev
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
#### Generate Client Code
|
||||
|
||||
To generate the client code you can use the command line application `openapi` that would now be installed.
|
||||
|
||||
Because it is installed in the local project, you probably wouldn't be able to call that command directly, but you would put it on your `package.json` file.
|
||||
|
||||
It could look like this:
|
||||
|
||||
```JSON hl_lines="7"
|
||||
{
|
||||
"name": "frontend-app",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"generate-client": "openapi --input http://localhost:8000/openapi.json --output ./src/client --client axios"
|
||||
},
|
||||
"author": "",
|
||||
"license": "",
|
||||
"devDependencies": {
|
||||
"openapi-typescript-codegen": "^0.20.1",
|
||||
"typescript": "^4.6.2"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
After having that NPM `generate-client` script there, you can run it with:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ npm run generate-client
|
||||
|
||||
frontend-app@1.0.0 generate-client /home/user/code/frontend-app
|
||||
> openapi --input http://localhost:8000/openapi.json --output ./src/client --client axios
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
That command will generate code in `./src/client` and will use `axios` (the frontend HTTP library) internally.
|
||||
|
||||
### Try Out the Client Code
|
||||
|
||||
Now you can import and use the client code, it could look like this, notice that you get autocompletion for the methods:
|
||||
|
||||
<img src="/img/tutorial/generate-clients/image02.png">
|
||||
|
||||
You will also get autocompletion for the payload to send:
|
||||
|
||||
<img src="/img/tutorial/generate-clients/image03.png">
|
||||
|
||||
!!! tip
|
||||
Notice the autocompletion for `name` and `price`, that was defined in the FastAPI application, in the `Item` model.
|
||||
|
||||
You will have inline errors for the data that you send:
|
||||
|
||||
<img src="/img/tutorial/generate-clients/image04.png">
|
||||
|
||||
The response object will also have autocompletion:
|
||||
|
||||
<img src="/img/tutorial/generate-clients/image05.png">
|
||||
|
||||
## FastAPI App with Tags
|
||||
|
||||
In many cases your FastAPI app will be bigger, and you will probably use tags to separate different groups of *path operations*.
|
||||
|
||||
For example, you could have a section for **items** and another section for **users**, and they could be separated by tags:
|
||||
|
||||
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="23 28 36"
|
||||
{!> ../../../docs_src/generate_clients/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="21 26 34"
|
||||
{!> ../../../docs_src/generate_clients/tutorial002_py39.py!}
|
||||
```
|
||||
|
||||
### Generate a TypeScript Client with Tags
|
||||
|
||||
If you generate a client for a FastAPI app using tags, it will normally also separate the client code based on the tags.
|
||||
|
||||
This way you will be able to have things ordered and grouped correctly for the client code:
|
||||
|
||||
<img src="/img/tutorial/generate-clients/image06.png">
|
||||
|
||||
In this case you have:
|
||||
|
||||
* `ItemsService`
|
||||
* `UsersService`
|
||||
|
||||
### Client Method Names
|
||||
|
||||
Right now the generated method names like `createItemItemsPost` don't look very clean:
|
||||
|
||||
```TypeScript
|
||||
ItemsService.createItemItemsPost({name: "Plumbus", price: 5})
|
||||
```
|
||||
|
||||
...that's because the client generator uses the OpenAPI internal **operation ID** for each *path operation*.
|
||||
|
||||
OpenAPI requires that each operation ID is unique across all the *path operations*, so FastAPI uses the **function name**, the **path**, and the **HTTP method/operation** to generate that operation ID, because that way it can make sure that the operation IDs are unique.
|
||||
|
||||
But I'll show you how to improve that next. 🤓
|
||||
|
||||
## Custom Operation IDs and Better Method Names
|
||||
|
||||
You can **modify** the way these operation IDs are **generated** to make them simpler and have **simpler method names** in the clients.
|
||||
|
||||
In this case you will have to ensure that each operation ID is **unique** in some other way.
|
||||
|
||||
For example, you could make sure that each *path operation* has a tag, and then generate the operation ID based on the **tag** and the *path operation* **name** (the function name).
|
||||
|
||||
### Custom Generate Unique ID Function
|
||||
|
||||
FastAPI uses a **unique ID** for each *path operation*, it is used for the **operation ID** and also for the names of any needed custom models, for requests or responses.
|
||||
|
||||
You can customize that function. It takes an `APIRoute` and outputs a string.
|
||||
|
||||
For example, here it is using the first tag (you will probably have only one tag) and the *path operation* name (the function name).
|
||||
|
||||
You can then pass that custom function to **FastAPI** as the `generate_unique_id_function` parameter:
|
||||
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="8-9 12"
|
||||
{!> ../../../docs_src/generate_clients/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="6-7 10"
|
||||
{!> ../../../docs_src/generate_clients/tutorial003_py39.py!}
|
||||
```
|
||||
|
||||
### Generate a TypeScript Client with Custom Operation IDs
|
||||
|
||||
Now if you generate the client again, you will see that it has the improved method names:
|
||||
|
||||
<img src="/img/tutorial/generate-clients/image07.png">
|
||||
|
||||
As you see, the method names now have the tag and then the function name, now they don't include information from the URL path and the HTTP operation.
|
||||
|
||||
### Preprocess the OpenAPI Specification for the Client Generator
|
||||
|
||||
The generated code still has some **duplicated information**.
|
||||
|
||||
We already know that this method is related to the **items** because that word is in the `ItemsService` (taken from the tag), but we still have the tag name prefixed in the method name too. 😕
|
||||
|
||||
We will probably still want to keep it for OpenAPI in general, as that will ensure that the operation IDs are **unique**.
|
||||
|
||||
But for the generated client we could **modify** the OpenAPI operation IDs right before generating the clients, just to make those method names nicer and **cleaner**.
|
||||
|
||||
We could download the OpenAPI JSON to a file `openapi.json` and then we could **remove that prefixed tag** with a script like this:
|
||||
|
||||
```Python
|
||||
{!../../../docs_src/generate_clients/tutorial004.py!}
|
||||
```
|
||||
|
||||
With that, the operation IDs would be renamed from things like `items-get_items` to just `get_items`, that way the client generator can generate simpler method names.
|
||||
|
||||
### Generate a TypeScript Client with the Preprocessed OpenAPI
|
||||
|
||||
Now as the end result is in a file `openapi.json`, you would modify the `package.json` to use that local file, for example:
|
||||
|
||||
```JSON hl_lines="7"
|
||||
{
|
||||
"name": "frontend-app",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"generate-client": "openapi --input ./openapi.json --output ./src/client --client axios"
|
||||
},
|
||||
"author": "",
|
||||
"license": "",
|
||||
"devDependencies": {
|
||||
"openapi-typescript-codegen": "^0.20.1",
|
||||
"typescript": "^4.6.2"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
After generating the new client, you would now have **clean method names**, with all the **autocompletion**, **inline errors**, etc:
|
||||
|
||||
<img src="/img/tutorial/generate-clients/image08.png">
|
||||
|
||||
## Benefits
|
||||
|
||||
When using the automatically generated clients you would **autocompletion** for:
|
||||
|
||||
* Methods.
|
||||
* Request payloads in the body, query parameters, etc.
|
||||
* Response payloads.
|
||||
|
||||
You would also have **inline errors** for everything.
|
||||
|
||||
And whenever you update the backend code, and **regenerate** the frontend, it would have any new *path operations* available as methods, the old ones removed, and any other change would be reflected on the generated code. 🤓
|
||||
|
||||
This also means that if something changed it will be **reflected** on the client code automatically. And if you **build** the client it will error out if you have any **mismatch** in the data used.
|
||||
|
||||
So, you would **detect many errors** very early in the development cycle instead of having to wait for the errors to show up to your final users in production and then trying to debug where the problem is. ✨
|
||||
@@ -116,7 +116,7 @@ The cashier 💁 gives you the number of your turn.
|
||||
|
||||
While you are waiting, you go with your crush 😍 and pick a table, you sit and talk with your crush 😍 for a long time (as your burgers are very fancy and take some time to prepare ✨🍔✨).
|
||||
|
||||
As you are sitting on the table with your crush 😍, while you wait for the burgers 🍔, you can spend that time admiring how awesome, cute and smart your crush is ✨😍✨.
|
||||
As you are sitting at the table with your crush 😍, while you wait for the burgers 🍔, you can spend that time admiring how awesome, cute and smart your crush is ✨😍✨.
|
||||
|
||||
While waiting and talking to your crush 😍, from time to time, you check the number displayed on the counter to see if it's your turn already.
|
||||
|
||||
@@ -134,7 +134,7 @@ Then, when it's your turn, you do actual "productive" work 🤓, you process the
|
||||
|
||||
But then, even though you still don't have your burgers 🍔, your work with the cashier 💁 is "on pause" ⏸, because you have to wait 🕙 for your burgers to be ready.
|
||||
|
||||
But as you go away from the counter and sit on the table with a number for your turn, you can switch 🔀 your attention to your crush 😍, and "work" ⏯ 🤓 on that. Then you are again doing something very "productive" 🤓, as is flirting with your crush 😍.
|
||||
But as you go away from the counter and sit at the table with a number for your turn, you can switch 🔀 your attention to your crush 😍, and "work" ⏯ 🤓 on that. Then you are again doing something very "productive" 🤓, as is flirting with your crush 😍.
|
||||
|
||||
Then the cashier 💁 says "I'm finished with doing the burgers" 🍔 by putting your number on the counter's display, but you don't jump like crazy immediately when the displayed number changes to your turn number. You know no one will steal your burgers 🍔 because you have the number of your turn, and they have theirs.
|
||||
|
||||
|
||||
22
docs/en/docs/img/sponsors/budget-insight.svg
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
docs/en/docs/img/sponsors/classiq-banner.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
docs/en/docs/img/sponsors/classiq.png
Normal file
|
After Width: | Height: | Size: 6.1 KiB |
117
docs/en/docs/img/sponsors/dropbase-banner.svg
Normal file
|
After Width: | Height: | Size: 21 KiB |
124
docs/en/docs/img/sponsors/dropbase.svg
Normal file
@@ -0,0 +1,124 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="240.00002"
|
||||
height="100"
|
||||
viewBox="0 0 240.00002 100"
|
||||
fill="none"
|
||||
version="1.1"
|
||||
id="svg35">
|
||||
<metadata
|
||||
id="metadata39">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<path
|
||||
d="M 0,0 H 240.00002 V 100 H 0 Z"
|
||||
fill="#ffffff"
|
||||
id="path2"
|
||||
style="stroke-width:0.0406002" />
|
||||
<g
|
||||
id="g908"
|
||||
transform="translate(0,8.4984581)">
|
||||
<path
|
||||
d="m 89.098346,53.723081 c 6.816739,0 10.858339,-4.216615 10.858339,-11.208001 0,-6.969268 -4.0416,-11.164025 -10.705478,-11.164025 h -7.733908 v 22.372026 z m -3.52837,-3.506585 V 34.857603 h 3.451939 c 4.544493,0 6.914955,2.5344 6.914955,7.657477 0,5.145232 -2.370462,7.701416 -7.034955,7.701416 z m 18.062774,3.506585 h 3.95446 v -9.86437 c 0,-2.130092 1.60578,-3.637661 3.77945,-3.637661 0.66646,0 1.49649,0.120369 1.83507,0.229661 v -3.637736 c -0.36037,-0.06554 -0.98289,-0.109255 -1.42006,-0.109255 -1.92258,0 -3.52837,1.092222 -4.14018,3.03696 h -0.17465 v -2.796554 h -3.83409 z m 18.82449,0.327877 c 4.91557,0 8.04,-3.463015 8.04,-8.651816 0,-5.199877 -3.12443,-8.673564 -8.04,-8.673564 -4.91594,0 -8.04,3.473687 -8.04,8.673564 0,5.188801 3.12406,8.651816 8.04,8.651816 z m 0.0218,-3.168 c -2.72013,0 -4.05268,-2.425108 -4.05268,-5.494893 0,-3.069415 1.33255,-5.527385 4.05268,-5.527385 2.67618,0 4.0091,2.45797 4.0091,5.527385 0,3.069785 -1.33292,5.494893 -4.0091,5.494893 z m 11.37452,9.132185 h 3.95446 v -8.935754 h 0.16357 c 0.62289,1.223631 1.92259,2.938708 4.80665,2.938708 3.95446,0 6.91458,-3.135139 6.91458,-8.662524 0,-5.593108 -3.04763,-8.629995 -6.92566,-8.629995 -2.96012,0 -4.19446,1.780764 -4.79557,2.993318 h -0.22929 v -2.77477 h -3.88874 z m 3.87766,-14.681724 c 0,-3.255139 1.39828,-5.363446 3.94376,-5.363446 2.63261,0 3.98695,2.239384 3.98695,5.363446 0,3.146216 -1.37612,5.440247 -3.98695,5.440247 -2.52333,0 -3.94376,-2.184739 -3.94376,-5.440247 z m 15.52283,8.389662 h 3.88911 v -2.643692 h 0.22929 c 0.62253,1.223631 1.92259,2.938708 4.80665,2.938708 3.95446,0 6.91459,-3.135139 6.91459,-8.662524 0,-5.593108 -3.04764,-8.629995 -6.92567,-8.629995 -2.96049,0 -4.19483,1.780764 -4.79557,2.993318 h -0.16393 v -8.367841 h -3.95447 z m 3.87803,-8.389662 c 0,-3.255139 1.39828,-5.363446 3.94339,-5.363446 2.63298,0 3.98732,2.239384 3.98732,5.363446 0,3.146216 -1.37649,5.440247 -3.98732,5.440247 -2.52332,0 -3.94339,-2.184739 -3.94339,-5.440247 z m 20.15188,8.728247 c 2.63262,0 4.20554,-1.234339 4.92665,-2.643692 h 0.13108 v 2.305107 h 3.8016 V 42.493296 c 0,-4.434831 -3.61588,-5.767718 -6.81674,-5.767718 -3.52837,0 -6.23742,1.572887 -7.11139,4.631595 l 3.69231,0.524307 c 0.39323,-1.14683 1.50757,-2.130092 3.44086,-2.130092 1.83545,0 2.8405,0.939692 2.8405,2.589046 v 0.06572 c 0,1.135754 -1.19077,1.1904 -4.15127,1.507201 -3.25514,0.349661 -6.36849,1.321846 -6.36849,5.101661 0,3.298708 2.41403,5.046647 5.61489,5.046647 z m 1.02683,-2.905846 c -1.64972,0 -2.82941,-0.7536 -2.82941,-2.206524 0,-1.518277 1.32184,-2.151877 3.09157,-2.403323 1.03754,-0.141785 3.11335,-0.403938 3.62658,-0.819323 v 1.977231 c 0,1.868308 -1.50757,3.451939 -3.88874,3.451939 z m 25.07004,-9.776863 c -0.5461,-2.840123 -2.81834,-4.653379 -6.75065,-4.653379 -4.04197,0 -6.79495,1.988271 -6.78388,5.090549 -0.0111,2.446892 1.4965,4.063754 4.71914,4.729846 l 2.86191,0.601108 c 1.54043,0.338584 2.26117,0.961108 2.26117,1.911508 0,1.146831 -1.24505,2.010092 -3.12406,2.010092 -1.8133,0 -2.99299,-0.786461 -3.33194,-2.294031 l -3.85588,0.371446 c 0.49145,3.080493 3.08049,4.904862 7.19889,4.904862 4.19447,0 7.15496,-2.174031 7.16604,-5.352739 -0.0111,-2.392246 -1.55114,-3.856246 -4.71914,-4.544492 l -2.86228,-0.611816 c -1.704,-0.382154 -2.38117,-0.972184 -2.37046,-1.944369 -0.0107,-1.136123 1.24541,-1.922585 2.89477,-1.922585 1.82437,0 2.78584,0.993969 3.09157,2.0976 z m 11.0496,12.672001 c 3.91089,0 6.59815,-1.911877 7.29711,-4.828431 l -3.69231,-0.415015 c -0.53539,1.420061 -1.84616,2.162585 -3.55016,2.162585 -2.55618,0 -4.24947,-1.682216 -4.28233,-4.555201 h 11.68873 v -1.212554 c 0,-5.887754 -3.53944,-8.476764 -7.66855,-8.476764 -4.80665,0 -7.94179,3.528333 -7.94179,8.706426 0,5.265231 3.09157,8.618954 8.1493,8.618954 z m -4.21662,-10.30117 c 0.12,-2.141169 1.704,-3.943754 4.06376,-3.943754 2.27224,0 3.8016,1.660431 3.82338,3.943754 z"
|
||||
fill="#161616"
|
||||
id="path4"
|
||||
style="stroke-width:0.0369231" />
|
||||
<g
|
||||
id="g898">
|
||||
<g
|
||||
filter="url(#filter0_d_2_165)"
|
||||
id="g8"
|
||||
transform="scale(0.03692308)">
|
||||
<rect
|
||||
x="454"
|
||||
y="401"
|
||||
width="1438"
|
||||
height="1438"
|
||||
rx="100"
|
||||
fill="#ffffff"
|
||||
id="rect6" />
|
||||
</g>
|
||||
<rect
|
||||
x="21.821541"
|
||||
y="19.864616"
|
||||
width="42.978466"
|
||||
height="42.978466"
|
||||
rx="2.9887683"
|
||||
fill="#161616"
|
||||
id="rect10"
|
||||
style="stroke-width:0.0369231" />
|
||||
<path
|
||||
d="m 41.202465,54.873605 h -7.07077 c -2.332837,0 -4.224,-1.891201 -4.224,-4.224001 V 32.064003 c 0,-2.332837 1.891163,-4.224001 4.224,-4.224001 h 7.07077 z"
|
||||
fill="#ffffff"
|
||||
id="path12"
|
||||
style="stroke-width:0.0369231" />
|
||||
<path
|
||||
d="m 45.437542,29.205086 c 0,-0.583201 0.472616,-1.056001 1.056,-1.056001 h 7.07077 c 1.749785,0 3.168,1.418364 3.168,3.168001 v 7.919963 c 0,0.583385 -0.472615,1.056001 -1.056,1.056001 h -7.070769 c -1.749785,0 -3.168001,-1.418216 -3.168001,-3.168001 z"
|
||||
fill="#ffffff"
|
||||
id="path14"
|
||||
style="stroke-width:0.0369231" />
|
||||
<path
|
||||
d="m 45.437542,43.77785 c 0,-0.583016 0.472616,-1.056 1.056,-1.056 h 7.07077 c 1.749785,0 3.168,1.418215 3.168,3.168 v 7.920001 c 0,0.583384 -0.472615,1.056 -1.056,1.056 h -7.070769 c -1.749785,0 -3.168001,-1.418216 -3.168001,-3.168001 z"
|
||||
fill="#ffffff"
|
||||
id="path16"
|
||||
style="stroke-width:0.0369231" />
|
||||
</g>
|
||||
</g>
|
||||
<defs
|
||||
id="defs33">
|
||||
<filter
|
||||
id="filter0_d_2_165"
|
||||
x="408"
|
||||
y="355"
|
||||
width="1538"
|
||||
height="1538"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood
|
||||
flood-opacity="0"
|
||||
result="BackgroundImageFix"
|
||||
id="feFlood18" />
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
id="feColorMatrix20" />
|
||||
<feOffset
|
||||
dx="4"
|
||||
dy="4"
|
||||
id="feOffset22" />
|
||||
<feGaussianBlur
|
||||
stdDeviation="25"
|
||||
id="feGaussianBlur24" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"
|
||||
id="feColorMatrix26" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_2_165"
|
||||
id="feBlend28" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_2_165"
|
||||
result="shape"
|
||||
id="feBlend30" />
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.3 KiB |
BIN
docs/en/docs/img/sponsors/exoflare.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
docs/en/docs/img/sponsors/fastapi-course-bundle-banner.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
docs/en/docs/img/sponsors/ines-course.jpg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
docs/en/docs/img/sponsors/striveworks-banner.png
Normal file
|
After Width: | Height: | Size: 9.5 KiB |
BIN
docs/en/docs/img/sponsors/striveworks.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
docs/en/docs/img/tutorial/extending-openapi/image02.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
docs/en/docs/img/tutorial/extending-openapi/image03.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
docs/en/docs/img/tutorial/extending-openapi/image04.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
docs/en/docs/img/tutorial/generate-clients/image01.png
Normal file
|
After Width: | Height: | Size: 76 KiB |
BIN
docs/en/docs/img/tutorial/generate-clients/image02.png
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
docs/en/docs/img/tutorial/generate-clients/image03.png
Normal file
|
After Width: | Height: | Size: 60 KiB |
BIN
docs/en/docs/img/tutorial/generate-clients/image04.png
Normal file
|
After Width: | Height: | Size: 53 KiB |
BIN
docs/en/docs/img/tutorial/generate-clients/image05.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
docs/en/docs/img/tutorial/generate-clients/image06.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
docs/en/docs/img/tutorial/generate-clients/image07.png
Normal file
|
After Width: | Height: | Size: 49 KiB |
BIN
docs/en/docs/img/tutorial/generate-clients/image08.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
@@ -148,37 +148,62 @@ You can use, for example:
|
||||
|
||||
There are some data structures that can contain other values, like `dict`, `list`, `set` and `tuple`. And the internal values can have their own type too.
|
||||
|
||||
To declare those types and the internal types, you can use the standard Python module `typing`.
|
||||
These types that have internal types are called "**generic**" types. And it's possible to declare them, even with their internal types.
|
||||
|
||||
It exists specifically to support these type hints.
|
||||
To declare those types and the internal types, you can use the standard Python module `typing`. It exists specifically to support these type hints.
|
||||
|
||||
#### `List`
|
||||
#### Newer versions of Python
|
||||
|
||||
The syntax using `typing` is **compatible** with all versions, from Python 3.6 to the latest ones, including Python 3.9, Python 3.10, etc.
|
||||
|
||||
As Python advances, **newer versions** come with improved support for these type annotations and in many cases you won't even need to import and use the `typing` module to declare the type annotations.
|
||||
|
||||
If you can chose a more recent version of Python for your project, you will be able to take advantage of that extra simplicity. See some examples below.
|
||||
|
||||
#### List
|
||||
|
||||
For example, let's define a variable to be a `list` of `str`.
|
||||
|
||||
From `typing`, import `List` (with a capital `L`):
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!../../../docs_src/python_types/tutorial006.py!}
|
||||
```
|
||||
From `typing`, import `List` (with a capital `L`):
|
||||
|
||||
Declare the variable, with the same colon (`:`) syntax.
|
||||
``` Python hl_lines="1"
|
||||
{!> ../../../docs_src/python_types/tutorial006.py!}
|
||||
```
|
||||
|
||||
As the type, put the `List`.
|
||||
Declare the variable, with the same colon (`:`) syntax.
|
||||
|
||||
As the list is a type that contains some internal types, you put them in square brackets:
|
||||
As the type, put the `List` that you imported from `typing`.
|
||||
|
||||
```Python hl_lines="4"
|
||||
{!../../../docs_src/python_types/tutorial006.py!}
|
||||
```
|
||||
As the list is a type that contains some internal types, you put them in square brackets:
|
||||
|
||||
!!! tip
|
||||
```Python hl_lines="4"
|
||||
{!> ../../../docs_src/python_types/tutorial006.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
Declare the variable, with the same colon (`:`) syntax.
|
||||
|
||||
As the type, put `list`.
|
||||
|
||||
As the list is a type that contains some internal types, you put them in square brackets:
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../../docs_src/python_types/tutorial006_py39.py!}
|
||||
```
|
||||
|
||||
!!! info
|
||||
Those internal types in the square brackets are called "type parameters".
|
||||
|
||||
In this case, `str` is the type parameter passed to `List`.
|
||||
In this case, `str` is the type parameter passed to `List` (or `list` in Python 3.9 and above).
|
||||
|
||||
That means: "the variable `items` is a `list`, and each of the items in this list is a `str`".
|
||||
|
||||
!!! tip
|
||||
If you use Python 3.9 or above, you don't have to import `List` from `typing`, you can use the same regular `list` type instead.
|
||||
|
||||
By doing that, your editor can provide support even while processing items from the list:
|
||||
|
||||
<img src="/img/python-types/image05.png">
|
||||
@@ -189,20 +214,28 @@ Notice that the variable `item` is one of the elements in the list `items`.
|
||||
|
||||
And still, the editor knows it is a `str`, and provides support for that.
|
||||
|
||||
#### `Tuple` and `Set`
|
||||
#### Tuple and Set
|
||||
|
||||
You would do the same to declare `tuple`s and `set`s:
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!../../../docs_src/python_types/tutorial007.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../../docs_src/python_types/tutorial007.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../../docs_src/python_types/tutorial007_py39.py!}
|
||||
```
|
||||
|
||||
This means:
|
||||
|
||||
* The variable `items_t` is a `tuple` with 3 items, an `int`, another `int`, and a `str`.
|
||||
* The variable `items_s` is a `set`, and each of its items is of type `bytes`.
|
||||
|
||||
#### `Dict`
|
||||
#### Dict
|
||||
|
||||
To define a `dict`, you pass 2 type parameters, separated by commas.
|
||||
|
||||
@@ -210,9 +243,17 @@ The first type parameter is for the keys of the `dict`.
|
||||
|
||||
The second type parameter is for the values of the `dict`:
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!../../../docs_src/python_types/tutorial008.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../../docs_src/python_types/tutorial008.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../../docs_src/python_types/tutorial008_py39.py!}
|
||||
```
|
||||
|
||||
This means:
|
||||
|
||||
@@ -220,9 +261,33 @@ This means:
|
||||
* The keys of this `dict` are of type `str` (let's say, the name of each item).
|
||||
* The values of this `dict` are of type `float` (let's say, the price of each item).
|
||||
|
||||
#### `Optional`
|
||||
#### Union
|
||||
|
||||
You can also use `Optional` to declare that a variable has a type, like `str`, but that it is "optional", which means that it could also be `None`:
|
||||
You can declare that a variable can be any of **several types**, for example, an `int` or a `str`.
|
||||
|
||||
In Python 3.6 and above (including Python 3.10) you can use the `Union` type from `typing` and put inside the square brackets the possible types to accept.
|
||||
|
||||
In Python 3.10 there's also an **alternative syntax** were you can put the possible types separated by a <abbr title='also called "bitwise or operator", but that meaning is not relevant here'>vertical bar (`|`)</abbr>.
|
||||
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../../docs_src/python_types/tutorial008b.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../../docs_src/python_types/tutorial008b_py310.py!}
|
||||
```
|
||||
|
||||
In both cases this means that `item` could be an `int` or a `str`.
|
||||
|
||||
#### Possibly `None`
|
||||
|
||||
You can declare that a value could have a type, like `str`, but that it could also be `None`.
|
||||
|
||||
In Python 3.6 and above (including Python 3.10) you can declare it by importing and using `Optional` from the `typing` module.
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!../../../docs_src/python_types/tutorial009.py!}
|
||||
@@ -230,18 +295,73 @@ You can also use `Optional` to declare that a variable has a type, like `str`, b
|
||||
|
||||
Using `Optional[str]` instead of just `str` will let the editor help you detecting errors where you could be assuming that a value is always a `str`, when it could actually be `None` too.
|
||||
|
||||
`Optional[Something]` is actually a shortcut for `Union[Something, None]`, they are equivalent.
|
||||
|
||||
This also means that in Python 3.10, you can use `Something | None`:
|
||||
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../../docs_src/python_types/tutorial009.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6 and above - alternative"
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../../docs_src/python_types/tutorial009b.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../../docs_src/python_types/tutorial009_py310.py!}
|
||||
```
|
||||
|
||||
#### Generic types
|
||||
|
||||
These types that take type parameters in square brackets, like:
|
||||
These types that take type parameters in square brackets are called **Generic types** or **Generics**, for example:
|
||||
|
||||
* `List`
|
||||
* `Tuple`
|
||||
* `Set`
|
||||
* `Dict`
|
||||
* `Optional`
|
||||
* ...and others.
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
are called **Generic types** or **Generics**.
|
||||
* `List`
|
||||
* `Tuple`
|
||||
* `Set`
|
||||
* `Dict`
|
||||
* `Union`
|
||||
* `Optional`
|
||||
* ...and others.
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
You can use the same builtin types as generics (with square brakets and types inside):
|
||||
|
||||
* `list`
|
||||
* `tuple`
|
||||
* `set`
|
||||
* `dict`
|
||||
|
||||
And the same as with Python 3.6, from the `typing` module:
|
||||
|
||||
* `Union`
|
||||
* `Optional`
|
||||
* ...and others.
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
You can use the same builtin types as generics (with square brakets and types inside):
|
||||
|
||||
* `list`
|
||||
* `tuple`
|
||||
* `set`
|
||||
* `dict`
|
||||
|
||||
And the same as with Python 3.6, from the `typing` module:
|
||||
|
||||
* `Union`
|
||||
* `Optional` (the same as with Python 3.6)
|
||||
* ...and others.
|
||||
|
||||
In Python 3.10, as an alternative to using the generics `Union` and `Optional`, you can use the <abbr title='also called "bitwise or operator", but that meaning is not relevant here'>vertical bar (`|`)</abbr> to declare unions of types.
|
||||
|
||||
### Classes as types
|
||||
|
||||
@@ -275,11 +395,25 @@ Then you create an instance of that class with some values and it will validate
|
||||
|
||||
And you get all the editor support with that resulting object.
|
||||
|
||||
Taken from the official Pydantic docs:
|
||||
An example from the official Pydantic docs:
|
||||
|
||||
```Python
|
||||
{!../../../docs_src/python_types/tutorial011.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python
|
||||
{!> ../../../docs_src/python_types/tutorial011.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python
|
||||
{!> ../../../docs_src/python_types/tutorial011_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python
|
||||
{!> ../../../docs_src/python_types/tutorial011_py310.py!}
|
||||
```
|
||||
|
||||
!!! info
|
||||
To learn more about <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic, check its docs</a>.
|
||||
|
||||
@@ -2,6 +2,234 @@
|
||||
|
||||
## Latest Changes
|
||||
|
||||
|
||||
## 0.77.0
|
||||
|
||||
### Upgrades
|
||||
|
||||
* ⬆ Upgrade Starlette from 0.18.0 to 0.19.0. PR [#4488](https://github.com/tiangolo/fastapi/pull/4488) by [@Kludex](https://github.com/Kludex).
|
||||
* When creating an explicit `JSONResponse` the `content` argument is now required.
|
||||
|
||||
### Docs
|
||||
|
||||
* 📝 Add external link to article: Seamless FastAPI Configuration with ConfZ. PR [#4414](https://github.com/tiangolo/fastapi/pull/4414) by [@silvanmelchior](https://github.com/silvanmelchior).
|
||||
* 📝 Add external link to article: 5 Advanced Features of FastAPI You Should Try. PR [#4436](https://github.com/tiangolo/fastapi/pull/4436) by [@kaustubhgupta](https://github.com/kaustubhgupta).
|
||||
* ✏ Reword to improve legibility of docs about `TestClient`. PR [#4389](https://github.com/tiangolo/fastapi/pull/4389) by [@rgilton](https://github.com/rgilton).
|
||||
* 📝 Add external link to blog post about Kafka, FastAPI, and Ably. PR [#4044](https://github.com/tiangolo/fastapi/pull/4044) by [@Ugbot](https://github.com/Ugbot).
|
||||
* ✏ Fix typo in `docs/en/docs/tutorial/sql-databases.md`. PR [#4875](https://github.com/tiangolo/fastapi/pull/4875) by [@wpyoga](https://github.com/wpyoga).
|
||||
* ✏ Fix typo in `docs/en/docs/async.md`. PR [#4726](https://github.com/tiangolo/fastapi/pull/4726) by [@Prezu](https://github.com/Prezu).
|
||||
|
||||
### Translations
|
||||
|
||||
* 🌐 Update source example highlights for `docs/zh/docs/tutorial/query-params-str-validations.md`. PR [#4237](https://github.com/tiangolo/fastapi/pull/4237) by [@caimaoy](https://github.com/caimaoy).
|
||||
* 🌐 Remove translation docs references to aiofiles as it's no longer needed since AnyIO. PR [#3594](https://github.com/tiangolo/fastapi/pull/3594) by [@alonme](https://github.com/alonme).
|
||||
* ✏ 🌐 Fix typo in Portuguese translation for `docs/pt/docs/tutorial/path-params.md`. PR [#4722](https://github.com/tiangolo/fastapi/pull/4722) by [@CleoMenezesJr](https://github.com/CleoMenezesJr).
|
||||
* 🌐 Fix live docs server for translations for some languages. PR [#4729](https://github.com/tiangolo/fastapi/pull/4729) by [@wakabame](https://github.com/wakabame).
|
||||
* 🌐 Add Portuguese translation for `docs/pt/docs/tutorial/cookie-params.md`. PR [#4112](https://github.com/tiangolo/fastapi/pull/4112) by [@lbmendes](https://github.com/lbmendes).
|
||||
* 🌐 Fix French translation for `docs/tutorial/body.md`. PR [#4332](https://github.com/tiangolo/fastapi/pull/4332) by [@Smlep](https://github.com/Smlep).
|
||||
* 🌐 Add Japanese translation for `docs/ja/docs/advanced/conditional-openapi.md`. PR [#2631](https://github.com/tiangolo/fastapi/pull/2631) by [@sh0nk](https://github.com/sh0nk).
|
||||
* 🌐 Fix Japanese translation of `docs/ja/docs/tutorial/body.md`. PR [#3062](https://github.com/tiangolo/fastapi/pull/3062) by [@a-takahashi223](https://github.com/a-takahashi223).
|
||||
* 🌐 Add Portuguese translation for `docs/pt/docs/tutorial/background-tasks.md`. PR [#2170](https://github.com/tiangolo/fastapi/pull/2170) by [@izaguerreiro](https://github.com/izaguerreiro).
|
||||
* 🌐 Add Portuguese translation for `docs/deployment/deta.md`. PR [#4442](https://github.com/tiangolo/fastapi/pull/4442) by [@lsglucas](https://github.com/lsglucas).
|
||||
* 🌐 Add Russian translation for `docs/async.md`. PR [#4036](https://github.com/tiangolo/fastapi/pull/4036) by [@Winand](https://github.com/Winand).
|
||||
* 🌐 Add Portuguese translation for `docs/tutorial/body.md`. PR [#3960](https://github.com/tiangolo/fastapi/pull/3960) by [@leandrodesouzadev](https://github.com/leandrodesouzadev).
|
||||
* 🌐 Add Portuguese translation of `tutorial/extra-data-types.md`. PR [#4077](https://github.com/tiangolo/fastapi/pull/4077) by [@luccasmmg](https://github.com/luccasmmg).
|
||||
* 🌐 Update German translation for `docs/features.md`. PR [#3905](https://github.com/tiangolo/fastapi/pull/3905) by [@jomue](https://github.com/jomue).
|
||||
|
||||
## 0.76.0
|
||||
|
||||
### Upgrades
|
||||
|
||||
* ⬆ Upgrade Starlette from 0.17.1 to 0.18.0. PR [#4483](https://github.com/tiangolo/fastapi/pull/4483) by [@Kludex](https://github.com/Kludex).
|
||||
|
||||
### Internal
|
||||
|
||||
* 👥 Update FastAPI People. PR [#4847](https://github.com/tiangolo/fastapi/pull/4847) by [@github-actions[bot]](https://github.com/apps/github-actions).
|
||||
* 🔧 Add Budget Insight sponsor. PR [#4824](https://github.com/tiangolo/fastapi/pull/4824) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 🍱 Update sponsor, ExoFlare badge. PR [#4822](https://github.com/tiangolo/fastapi/pull/4822) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 🔧 Update sponsors, enable Dropbase again, update TalkPython link. PR [#4821](https://github.com/tiangolo/fastapi/pull/4821) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
## 0.75.2
|
||||
|
||||
This release includes upgrades to third-party packages that handle security issues. Although there's a chance these issues don't affect you in particular, please upgrade as soon as possible.
|
||||
|
||||
### Fixes
|
||||
|
||||
* ✅ Fix new/recent tests with new fixed `ValidationError` JSON Schema. PR [#4806](https://github.com/tiangolo/fastapi/pull/4806) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 🐛 Fix JSON Schema for `ValidationError` at field `loc`. PR [#3810](https://github.com/tiangolo/fastapi/pull/3810) by [@dconathan](https://github.com/dconathan).
|
||||
* 🐛 Fix support for prefix on APIRouter WebSockets. PR [#2640](https://github.com/tiangolo/fastapi/pull/2640) by [@Kludex](https://github.com/Kludex).
|
||||
|
||||
### Upgrades
|
||||
|
||||
* ⬆️ Update ujson ranges for CVE-2021-45958. PR [#4804](https://github.com/tiangolo/fastapi/pull/4804) by [@tiangolo](https://github.com/tiangolo).
|
||||
* ⬆️ Upgrade dependencies upper range for extras "all". PR [#4803](https://github.com/tiangolo/fastapi/pull/4803) by [@tiangolo](https://github.com/tiangolo).
|
||||
* ⬆ Upgrade Swagger UI - swagger-ui-dist@4. This handles a security issue in Swagger UI itself where it could be possible to inject HTML into Swagger UI. Please upgrade as soon as you can, in particular if you expose your Swagger UI (`/docs`) publicly to non-expert users. PR [#4347](https://github.com/tiangolo/fastapi/pull/4347) by [@RAlanWright](https://github.com/RAlanWright).
|
||||
|
||||
### Internal
|
||||
|
||||
* 🔧 Update sponsors, add: ExoFlare, Ines Course; remove: Dropbase, Vim.so, Calmcode; update: Striveworks, TalkPython and TestDriven.io. PR [#4805](https://github.com/tiangolo/fastapi/pull/4805) by [@tiangolo](https://github.com/tiangolo).
|
||||
* ⬆️ Upgrade Codecov GitHub Action. PR [#4801](https://github.com/tiangolo/fastapi/pull/4801) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
## 0.75.1
|
||||
|
||||
### Translations
|
||||
|
||||
* 🌐 Start Dutch translations. PR [#4703](https://github.com/tiangolo/fastapi/pull/4703) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 🌐 Start Persian/Farsi translations. PR [#4243](https://github.com/tiangolo/fastapi/pull/4243) by [@aminalaee](https://github.com/aminalaee).
|
||||
* ✏ Reword sentence about handling errors. PR [#1993](https://github.com/tiangolo/fastapi/pull/1993) by [@khuhroproeza](https://github.com/khuhroproeza).
|
||||
|
||||
### Internal
|
||||
|
||||
* 👥 Update FastAPI People. PR [#4752](https://github.com/tiangolo/fastapi/pull/4752) by [@github-actions[bot]](https://github.com/apps/github-actions).
|
||||
* ➖ Temporarily remove typer-cli from dependencies and upgrade Black to unblock Pydantic CI. PR [#4754](https://github.com/tiangolo/fastapi/pull/4754) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 🔧 Add configuration to notify Dutch translations. PR [#4702](https://github.com/tiangolo/fastapi/pull/4702) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 👥 Update FastAPI People. PR [#4699](https://github.com/tiangolo/fastapi/pull/4699) by [@github-actions[bot]](https://github.com/apps/github-actions).
|
||||
* 🐛 Fix FastAPI People generation to include missing file in commit. PR [#4695](https://github.com/tiangolo/fastapi/pull/4695) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 🔧 Update Classiq sponsor links. PR [#4688](https://github.com/tiangolo/fastapi/pull/4688) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 🔧 Add Classiq sponsor. PR [#4671](https://github.com/tiangolo/fastapi/pull/4671) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 📝 Add Jina's QA Bot to the docs to help people that want to ask quick questions. PR [#4655](https://github.com/tiangolo/fastapi/pull/4655) by [@tiangolo](https://github.com/tiangolo) based on original PR [#4626](https://github.com/tiangolo/fastapi/pull/4626) by [@hanxiao](https://github.com/hanxiao).
|
||||
|
||||
## 0.75.0
|
||||
|
||||
### Features
|
||||
|
||||
* ✨ Add support for custom `generate_unique_id_function` and docs for generating clients. New docs: [Advanced - Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/). PR [#4650](https://github.com/tiangolo/fastapi/pull/4650) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
## 0.74.1
|
||||
|
||||
### Features
|
||||
|
||||
* ✨ Include route in scope to allow middleware and other tools to extract its information. PR [#4603](https://github.com/tiangolo/fastapi/pull/4603) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
## 0.74.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* ✨ Update internal `AsyncExitStack` to fix context for dependencies with `yield`. PR [#4575](https://github.com/tiangolo/fastapi/pull/4575) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
Dependencies with `yield` can now catch `HTTPException` and custom exceptions. For example:
|
||||
|
||||
```Python
|
||||
async def get_database():
|
||||
with Session() as session:
|
||||
try:
|
||||
yield session
|
||||
except HTTPException:
|
||||
session.rollback()
|
||||
raise
|
||||
finally:
|
||||
session.close()
|
||||
```
|
||||
|
||||
After the dependency with `yield` handles the exception (or not) the exception is raised again. So that any exception handlers can catch it, or ultimately the default internal `ServerErrorMiddleware`.
|
||||
|
||||
If you depended on exceptions not being received by dependencies with `yield`, and receiving an exception breaks the code after `yield`, you can use a block with `try` and `finally`:
|
||||
|
||||
```Python
|
||||
async def do_something():
|
||||
try:
|
||||
yield something
|
||||
finally:
|
||||
some_cleanup()
|
||||
```
|
||||
|
||||
...that way the `finally` block is run regardless of any exception that might happen.
|
||||
|
||||
### Features
|
||||
|
||||
* The same PR [#4575](https://github.com/tiangolo/fastapi/pull/4575) from above also fixes the `contextvars` context for the code before and after `yield`. This was the main objective of that PR.
|
||||
|
||||
This means that now, if you set a value in a context variable before `yield`, the value would still be available after `yield` (as you would intuitively expect). And it also means that you can reset the context variable with a token afterwards.
|
||||
|
||||
For example, this works correctly now:
|
||||
|
||||
```Python
|
||||
from contextvars import ContextVar
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
|
||||
legacy_request_state_context_var: ContextVar[Optional[Dict[str, Any]]] = ContextVar(
|
||||
"legacy_request_state_context_var", default=None
|
||||
)
|
||||
|
||||
async def set_up_request_state_dependency():
|
||||
request_state = {"user": "deadpond"}
|
||||
contextvar_token = legacy_request_state_context_var.set(request_state)
|
||||
yield request_state
|
||||
legacy_request_state_context_var.reset(contextvar_token)
|
||||
```
|
||||
|
||||
...before this change it would raise an error when resetting the context variable, because the `contextvars` context was different, because of the way it was implemented.
|
||||
|
||||
**Note**: You probably don't need `contextvars`, and you should probably avoid using them. But they are powerful and useful in some advanced scenarios, for example, migrating from code that used Flask's `g` semi-global variable.
|
||||
|
||||
**Technical Details**: If you want to know more of the technical details you can check out the PR description [#4575](https://github.com/tiangolo/fastapi/pull/4575).
|
||||
|
||||
### Internal
|
||||
|
||||
* 🔧 Add Striveworks sponsor. PR [#4596](https://github.com/tiangolo/fastapi/pull/4596) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 💚 Only build docs on push when on master to avoid duplicate runs from PRs. PR [#4564](https://github.com/tiangolo/fastapi/pull/4564) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 👥 Update FastAPI People. PR [#4502](https://github.com/tiangolo/fastapi/pull/4502) by [@github-actions[bot]](https://github.com/apps/github-actions).
|
||||
|
||||
## 0.73.0
|
||||
|
||||
### Features
|
||||
|
||||
* ✨ Add support for declaring `UploadFile` parameters without explicit `File()`. PR [#4469](https://github.com/tiangolo/fastapi/pull/4469) by [@tiangolo](https://github.com/tiangolo). New docs: [Request Files - File Parameters with UploadFile](https://fastapi.tiangolo.com/tutorial/request-files/#file-parameters-with-uploadfile).
|
||||
* ✨ Add support for tags with Enums. PR [#4468](https://github.com/tiangolo/fastapi/pull/4468) by [@tiangolo](https://github.com/tiangolo). New docs: [Path Operation Configuration - Tags with Enums](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags-with-enums).
|
||||
* ✨ Allow hiding from OpenAPI (and Swagger UI) `Query`, `Cookie`, `Header`, and `Path` parameters. PR [#3144](https://github.com/tiangolo/fastapi/pull/3144) by [@astraldawn](https://github.com/astraldawn). New docs: [Query Parameters and String Validations - Exclude from OpenAPI](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
|
||||
|
||||
### Docs
|
||||
|
||||
* 📝 Tweak and improve docs for Request Files. PR [#4470](https://github.com/tiangolo/fastapi/pull/4470) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
### Fixes
|
||||
|
||||
* 🐛 Fix bug preventing to use OpenAPI when using tuples. PR [#3874](https://github.com/tiangolo/fastapi/pull/3874) by [@victorbenichoux](https://github.com/victorbenichoux).
|
||||
* 🐛 Prefer custom encoder over defaults if specified in `jsonable_encoder`. PR [#2061](https://github.com/tiangolo/fastapi/pull/2061) by [@viveksunder](https://github.com/viveksunder).
|
||||
* 💚 Duplicate PR to trigger CI. PR [#4467](https://github.com/tiangolo/fastapi/pull/4467) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
### Internal
|
||||
|
||||
* 🐛 Fix docs dependencies cache, to get the latest Material for MkDocs. PR [#4466](https://github.com/tiangolo/fastapi/pull/4466) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 🔧 Add sponsor Dropbase. PR [#4465](https://github.com/tiangolo/fastapi/pull/4465) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
## 0.72.0
|
||||
|
||||
### Features
|
||||
|
||||
* ✨ Enable configuring Swagger UI parameters. Original PR [#2568](https://github.com/tiangolo/fastapi/pull/2568) by [@jmriebold](https://github.com/jmriebold). Here are the new docs: [Configuring Swagger UI](https://fastapi.tiangolo.com/advanced/extending-openapi/#configuring-swagger-ui).
|
||||
|
||||
### Docs
|
||||
|
||||
* 📝 Update Python Types docs, add missing 3.6 / 3.9 example. PR [#4434](https://github.com/tiangolo/fastapi/pull/4434) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
### Translations
|
||||
|
||||
* 🌐 Update Chinese translation for `docs/help-fastapi.md`. PR [#3847](https://github.com/tiangolo/fastapi/pull/3847) by [@jaystone776](https://github.com/jaystone776).
|
||||
* 🌐 Fix Korean translation for `docs/ko/docs/index.md`. PR [#4195](https://github.com/tiangolo/fastapi/pull/4195) by [@kty4119](https://github.com/kty4119).
|
||||
* 🌐 Add Polish translation for `docs/pl/docs/index.md`. PR [#4245](https://github.com/tiangolo/fastapi/pull/4245) by [@MicroPanda123](https://github.com/MicroPanda123).
|
||||
* 🌐 Add Chinese translation for `docs\tutorial\path-operation-configuration.md`. PR [#3312](https://github.com/tiangolo/fastapi/pull/3312) by [@jaystone776](https://github.com/jaystone776).
|
||||
|
||||
### Internal
|
||||
|
||||
* 🔧 Enable MkDocs Material Insiders' `content.tabs.link`. PR [#4399](https://github.com/tiangolo/fastapi/pull/4399) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
## 0.71.0
|
||||
|
||||
### Features
|
||||
|
||||
* ✨ Add docs and tests for Python 3.9 and Python 3.10. PR [#3712](https://github.com/tiangolo/fastapi/pull/3712) by [@tiangolo](https://github.com/tiangolo).
|
||||
* You can start with [Python Types Intro](https://fastapi.tiangolo.com/python-types/), it explains what changes between different Python versions, in Python 3.9 and in Python 3.10.
|
||||
* All the FastAPI docs are updated. Each code example in the docs that could use different syntax in Python 3.9 or Python 3.10 now has all the alternatives in tabs.
|
||||
* ⬆️ Upgrade Starlette to 0.17.1. PR [#4145](https://github.com/tiangolo/fastapi/pull/4145) by [@simondale00](https://github.com/simondale00).
|
||||
|
||||
### Internal
|
||||
|
||||
* 👥 Update FastAPI People. PR [#4354](https://github.com/tiangolo/fastapi/pull/4354) by [@github-actions[bot]](https://github.com/apps/github-actions).
|
||||
* 🔧 Add FastAPI Trove Classifier for PyPI as now there's one 🤷😁. PR [#4386](https://github.com/tiangolo/fastapi/pull/4386) by [@tiangolo](https://github.com/tiangolo).
|
||||
* ⬆ Upgrade MkDocs Material and configs. PR [#4385](https://github.com/tiangolo/fastapi/pull/4385) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
## 0.70.1
|
||||
|
||||
There's nothing interesting in this particular FastAPI release. It is mainly to enable/unblock the release of the next version of Pydantic that comes packed with features and improvements. 🤩
|
||||
|
||||
@@ -57,9 +57,17 @@ Using `BackgroundTasks` also works with the dependency injection system, you can
|
||||
|
||||
**FastAPI** knows what to do in each case and how to re-use the same object, so that all the background tasks are merged together and are run in the background afterwards:
|
||||
|
||||
```Python hl_lines="13 15 22 25"
|
||||
{!../../../docs_src/background_tasks/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="13 15 22 25"
|
||||
{!> ../../../docs_src/background_tasks/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="11 13 20 23"
|
||||
{!> ../../../docs_src/background_tasks/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
In this example, the messages will be written to the `log.txt` file *after* the response is sent.
|
||||
|
||||
|
||||
@@ -6,9 +6,17 @@ The same way you can declare additional validation and metadata in *path operati
|
||||
|
||||
First, you have to import it:
|
||||
|
||||
```Python hl_lines="4"
|
||||
{!../../../docs_src/body_fields/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="4"
|
||||
{!> ../../../docs_src/body_fields/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="2"
|
||||
{!> ../../../docs_src/body_fields/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
!!! warning
|
||||
Notice that `Field` is imported directly from `pydantic`, not from `fastapi` as are all the rest (`Query`, `Path`, `Body`, etc).
|
||||
@@ -17,9 +25,17 @@ First, you have to import it:
|
||||
|
||||
You can then use `Field` with model attributes:
|
||||
|
||||
```Python hl_lines="11-14"
|
||||
{!../../../docs_src/body_fields/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="11-14"
|
||||
{!> ../../../docs_src/body_fields/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="9-12"
|
||||
{!> ../../../docs_src/body_fields/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
`Field` works the same way as `Query`, `Path` and `Body`, it has all the same parameters, etc.
|
||||
|
||||
|
||||
@@ -8,9 +8,17 @@ First, of course, you can mix `Path`, `Query` and request body parameter declara
|
||||
|
||||
And you can also declare body parameters as optional, by setting the default to `None`:
|
||||
|
||||
```Python hl_lines="19-21"
|
||||
{!../../../docs_src/body_multiple_params/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="19-21"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="17-19"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
!!! note
|
||||
Notice that, in this case, the `item` that would be taken from the body is optional. As it has a `None` default value.
|
||||
@@ -30,9 +38,17 @@ In the previous example, the *path operations* would expect a JSON body with the
|
||||
|
||||
But you can also declare multiple body parameters, e.g. `item` and `user`:
|
||||
|
||||
```Python hl_lines="22"
|
||||
{!../../../docs_src/body_multiple_params/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="22"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
In this case, **FastAPI** will notice that there are more than one body parameters in the function (two parameters that are Pydantic models).
|
||||
|
||||
@@ -71,14 +87,20 @@ If you declare it as is, because it is a singular value, **FastAPI** will assume
|
||||
|
||||
But you can instruct **FastAPI** to treat it as another body key using `Body`:
|
||||
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="23"
|
||||
{!../../../docs_src/body_multiple_params/tutorial003.py!}
|
||||
```
|
||||
```Python hl_lines="23"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="21"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
In this case, **FastAPI** will expect a body like:
|
||||
|
||||
|
||||
```JSON
|
||||
{
|
||||
"item": {
|
||||
@@ -107,12 +129,26 @@ As, by default, singular values are interpreted as query parameters, you don't h
|
||||
q: Optional[str] = None
|
||||
```
|
||||
|
||||
as in:
|
||||
Or in Python 3.10 and above:
|
||||
|
||||
```Python hl_lines="28"
|
||||
{!../../../docs_src/body_multiple_params/tutorial004.py!}
|
||||
```Python
|
||||
q: str | None = None
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="28"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial004.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="26"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
!!! info
|
||||
`Body` also has all the same extra validation and metadata parameters as `Query`,`Path` and others you will see later.
|
||||
|
||||
@@ -131,9 +167,17 @@ item: Item = Body(..., embed=True)
|
||||
|
||||
as in:
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!../../../docs_src/body_multiple_params/tutorial005.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial005.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="15"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
In this case **FastAPI** will expect a body like:
|
||||
|
||||
|
||||
@@ -6,9 +6,17 @@ With **FastAPI**, you can define, validate, document, and use arbitrarily deeply
|
||||
|
||||
You can define an attribute to be a subtype. For example, a Python `list`:
|
||||
|
||||
```Python hl_lines="14"
|
||||
{!../../../docs_src/body_nested_models/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="14"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
This will make `tags` be a list of items. Although it doesn't declare the type of each of the items.
|
||||
|
||||
@@ -18,19 +26,29 @@ But Python has a specific way to declare lists with internal types, or "type par
|
||||
|
||||
### Import typing's `List`
|
||||
|
||||
First, import `List` from standard Python's `typing` module:
|
||||
In Python 3.9 and above you can use the standard `list` to declare these type annotations as we'll see below. 💡
|
||||
|
||||
But in Python versions before 3.9 (3.6 and above), you first need to import `List` from standard Python's `typing` module:
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!../../../docs_src/body_nested_models/tutorial002.py!}
|
||||
{!> ../../../docs_src/body_nested_models/tutorial002.py!}
|
||||
```
|
||||
|
||||
### Declare a `List` with a type parameter
|
||||
### Declare a `list` with a type parameter
|
||||
|
||||
To declare types that have type parameters (internal types), like `list`, `dict`, `tuple`:
|
||||
|
||||
* Import them from the `typing` module
|
||||
* If you are in a Python version lower than 3.9, import their equivalent version from the `typing` module
|
||||
* Pass the internal type(s) as "type parameters" using square brackets: `[` and `]`
|
||||
|
||||
In Python 3.9 it would be:
|
||||
|
||||
```Python
|
||||
my_list: list[str]
|
||||
```
|
||||
|
||||
In versions of Python before 3.9, it would be:
|
||||
|
||||
```Python
|
||||
from typing import List
|
||||
|
||||
@@ -43,9 +61,23 @@ Use that same standard syntax for model attributes with internal types.
|
||||
|
||||
So, in our example, we can make `tags` be specifically a "list of strings":
|
||||
|
||||
```Python hl_lines="14"
|
||||
{!../../../docs_src/body_nested_models/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="14"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="14"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial002_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
## Set types
|
||||
|
||||
@@ -53,11 +85,25 @@ But then we think about it, and realize that tags shouldn't repeat, they would p
|
||||
|
||||
And Python has a special data type for sets of unique items, the `set`.
|
||||
|
||||
Then we can import `Set` and declare `tags` as a `set` of `str`:
|
||||
Then we can declare `tags` as a set of strings:
|
||||
|
||||
```Python hl_lines="1 14"
|
||||
{!../../../docs_src/body_nested_models/tutorial003.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="1 14"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="14"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial003_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
With this, even if you receive a request with duplicate data, it will be converted to a set of unique items.
|
||||
|
||||
@@ -79,17 +125,45 @@ All that, arbitrarily nested.
|
||||
|
||||
For example, we can define an `Image` model:
|
||||
|
||||
```Python hl_lines="9-11"
|
||||
{!../../../docs_src/body_nested_models/tutorial004.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="9-11"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial004.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="9-11"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial004_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="7-9"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
### Use the submodel as a type
|
||||
|
||||
And then we can use it as the type of an attribute:
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!../../../docs_src/body_nested_models/tutorial004.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial004.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial004_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
This would mean that **FastAPI** would expect a body similar to:
|
||||
|
||||
@@ -122,9 +196,23 @@ To see all the options you have, checkout the docs for <a href="https://pydantic
|
||||
|
||||
For example, as in the `Image` model we have a `url` field, we can declare it to be instead of a `str`, a Pydantic's `HttpUrl`:
|
||||
|
||||
```Python hl_lines="4 10"
|
||||
{!../../../docs_src/body_nested_models/tutorial005.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="4 10"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial005.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="4 10"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial005_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="2 8"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
The string will be checked to be a valid URL, and documented in JSON Schema / OpenAPI as such.
|
||||
|
||||
@@ -132,9 +220,23 @@ The string will be checked to be a valid URL, and documented in JSON Schema / Op
|
||||
|
||||
You can also use Pydantic models as subtypes of `list`, `set`, etc:
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!../../../docs_src/body_nested_models/tutorial006.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial006.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial006_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial006_py310.py!}
|
||||
```
|
||||
|
||||
This will expect (convert, validate, document, etc) a JSON body like:
|
||||
|
||||
@@ -169,9 +271,23 @@ This will expect (convert, validate, document, etc) a JSON body like:
|
||||
|
||||
You can define arbitrarily deeply nested models:
|
||||
|
||||
```Python hl_lines="9 14 20 23 27"
|
||||
{!../../../docs_src/body_nested_models/tutorial007.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="9 14 20 23 27"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial007.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="9 14 20 23 27"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial007_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="7 12 18 21 25"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial007_py310.py!}
|
||||
```
|
||||
|
||||
!!! info
|
||||
Notice how `Offer` has a list of `Item`s, which in turn have an optional list of `Image`s
|
||||
@@ -184,11 +300,25 @@ If the top level value of the JSON body you expect is a JSON `array` (a Python `
|
||||
images: List[Image]
|
||||
```
|
||||
|
||||
or in Python 3.9 and above:
|
||||
|
||||
```Python
|
||||
images: list[Image]
|
||||
```
|
||||
|
||||
as in:
|
||||
|
||||
```Python hl_lines="15"
|
||||
{!../../../docs_src/body_nested_models/tutorial008.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="15"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial008.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="13"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial008_py39.py!}
|
||||
```
|
||||
|
||||
## Editor support everywhere
|
||||
|
||||
@@ -218,9 +348,17 @@ That's what we are going to see here.
|
||||
|
||||
In this case, you would accept any `dict` as long as it has `int` keys with `float` values:
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../../docs_src/body_nested_models/tutorial009.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial009.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial009_py39.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
Have in mind that JSON only supports `str` as keys.
|
||||
|
||||
@@ -6,9 +6,23 @@ To update an item you can use the <a href="https://developer.mozilla.org/en-US/d
|
||||
|
||||
You can use the `jsonable_encoder` to convert the input data to data that can be stored as JSON (e.g. with a NoSQL database). For example, converting `datetime` to `str`.
|
||||
|
||||
```Python hl_lines="30-35"
|
||||
{!../../../docs_src/body_updates/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="30-35"
|
||||
{!> ../../../docs_src/body_updates/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="30-35"
|
||||
{!> ../../../docs_src/body_updates/tutorial001_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="28-33"
|
||||
{!> ../../../docs_src/body_updates/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
`PUT` is used to receive data that should replace the existing data.
|
||||
|
||||
@@ -53,9 +67,23 @@ That would generate a `dict` with only the data that was set when creating the `
|
||||
|
||||
Then you can use this to generate a `dict` with only the data that was set (sent in the request), omitting default values:
|
||||
|
||||
```Python hl_lines="34"
|
||||
{!../../../docs_src/body_updates/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="34"
|
||||
{!> ../../../docs_src/body_updates/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="34"
|
||||
{!> ../../../docs_src/body_updates/tutorial002_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="32"
|
||||
{!> ../../../docs_src/body_updates/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
### Using Pydantic's `update` parameter
|
||||
|
||||
@@ -63,9 +91,23 @@ Now, you can create a copy of the existing model using `.copy()`, and pass the `
|
||||
|
||||
Like `stored_item_model.copy(update=update_data)`:
|
||||
|
||||
```Python hl_lines="35"
|
||||
{!../../../docs_src/body_updates/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="35"
|
||||
{!> ../../../docs_src/body_updates/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="35"
|
||||
{!> ../../../docs_src/body_updates/tutorial002_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="33"
|
||||
{!> ../../../docs_src/body_updates/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
### Partial updates recap
|
||||
|
||||
@@ -82,9 +124,23 @@ In summary, to apply partial updates you would:
|
||||
* Save the data to your DB.
|
||||
* Return the updated model.
|
||||
|
||||
```Python hl_lines="30-37"
|
||||
{!../../../docs_src/body_updates/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="30-37"
|
||||
{!> ../../../docs_src/body_updates/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="30-37"
|
||||
{!> ../../../docs_src/body_updates/tutorial002_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="28-35"
|
||||
{!> ../../../docs_src/body_updates/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
You can actually use this same technique with an HTTP `PUT` operation.
|
||||
|
||||
@@ -19,9 +19,17 @@ To declare a **request** body, you use <a href="https://pydantic-docs.helpmanual
|
||||
|
||||
First, you need to import `BaseModel` from `pydantic`:
|
||||
|
||||
```Python hl_lines="4"
|
||||
{!../../../docs_src/body/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="4"
|
||||
{!> ../../../docs_src/body/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="2"
|
||||
{!> ../../../docs_src/body/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
## Create your data model
|
||||
|
||||
@@ -29,9 +37,17 @@ Then you declare your data model as a class that inherits from `BaseModel`.
|
||||
|
||||
Use standard Python types for all the attributes:
|
||||
|
||||
```Python hl_lines="7-11"
|
||||
{!../../../docs_src/body/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="7-11"
|
||||
{!> ../../../docs_src/body/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="5-9"
|
||||
{!> ../../../docs_src/body/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
The same as when declaring query parameters, when a model attribute has a default value, it is not required. Otherwise, it is required. Use `None` to make it just optional.
|
||||
|
||||
@@ -59,9 +75,17 @@ For example, this model above declares a JSON "`object`" (or Python `dict`) like
|
||||
|
||||
To add it to your *path operation*, declare it the same way you declared path and query parameters:
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!../../../docs_src/body/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!> ../../../docs_src/body/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="16"
|
||||
{!> ../../../docs_src/body/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
...and declare its type as the model you created, `Item`.
|
||||
|
||||
@@ -125,9 +149,17 @@ But you would get the same editor support with <a href="https://www.jetbrains.co
|
||||
|
||||
Inside of the function, you can access all the attributes of the model object directly:
|
||||
|
||||
```Python hl_lines="21"
|
||||
{!../../../docs_src/body/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="21"
|
||||
{!> ../../../docs_src/body/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/body/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
## Request body + path parameters
|
||||
|
||||
@@ -135,9 +167,17 @@ You can declare path parameters and request body at the same time.
|
||||
|
||||
**FastAPI** will recognize that the function parameters that match path parameters should be **taken from the path**, and that function parameters that are declared to be Pydantic models should be **taken from the request body**.
|
||||
|
||||
```Python hl_lines="17-18"
|
||||
{!../../../docs_src/body/tutorial003.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="17-18"
|
||||
{!> ../../../docs_src/body/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="15-16"
|
||||
{!> ../../../docs_src/body/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
## Request body + path + query parameters
|
||||
|
||||
@@ -145,9 +185,17 @@ You can also declare **body**, **path** and **query** parameters, all at the sam
|
||||
|
||||
**FastAPI** will recognize each of them and take the data from the correct place.
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!../../../docs_src/body/tutorial004.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!> ../../../docs_src/body/tutorial004.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="16"
|
||||
{!> ../../../docs_src/body/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
The function parameters will be recognized as follows:
|
||||
|
||||
|
||||
@@ -6,9 +6,17 @@ You can define Cookie parameters the same way you define `Query` and `Path` para
|
||||
|
||||
First import `Cookie`:
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!../../../docs_src/cookie_params/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../../docs_src/cookie_params/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
## Declare `Cookie` parameters
|
||||
|
||||
@@ -16,9 +24,17 @@ Then declare the cookie parameters using the same structure as with `Path` and `
|
||||
|
||||
The first value is the default value, you can pass all the extra validation or annotation parameters:
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../../docs_src/cookie_params/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/cookie_params/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/cookie_params/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
!!! note "Technical Details"
|
||||
`Cookie` is a "sister" class of `Path` and `Query`. It also inherits from the same common `Param` class.
|
||||
|
||||
@@ -6,9 +6,17 @@ Before diving deeper into the **Dependency Injection** system, let's upgrade the
|
||||
|
||||
In the previous example, we were returning a `dict` from our dependency ("dependable"):
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
But then we get a `dict` in the parameter `commons` of the *path operation function*.
|
||||
|
||||
@@ -71,21 +79,45 @@ That also applies to callables with no parameters at all. The same as it would b
|
||||
|
||||
Then, we can change the dependency "dependable" `common_parameters` from above to the class `CommonQueryParams`:
|
||||
|
||||
```Python hl_lines="11-15"
|
||||
{!../../../docs_src/dependencies/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="11-15"
|
||||
{!> ../../../docs_src/dependencies/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="9-13"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
Pay attention to the `__init__` method used to create the instance of the class:
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!../../../docs_src/dependencies/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../../docs_src/dependencies/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
...it has the same parameters as our previous `common_parameters`:
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
Those parameters are what **FastAPI** will use to "solve" the dependency.
|
||||
|
||||
@@ -101,9 +133,17 @@ In both cases the data will be converted, validated, documented on the OpenAPI s
|
||||
|
||||
Now you can declare your dependency using this class.
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!../../../docs_src/dependencies/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/dependencies/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
**FastAPI** calls the `CommonQueryParams` class. This creates an "instance" of that class and the instance will be passed as the parameter `commons` to your function.
|
||||
|
||||
@@ -143,9 +183,17 @@ commons = Depends(CommonQueryParams)
|
||||
|
||||
..as in:
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!../../../docs_src/dependencies/tutorial003.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/dependencies/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
But declaring the type is encouraged as that way your editor will know what will be passed as the parameter `commons`, and then it can help you with code completion, type checks, etc:
|
||||
|
||||
@@ -179,9 +227,17 @@ You declare the dependency as the type of the parameter, and you use `Depends()`
|
||||
|
||||
The same example would then look like:
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!../../../docs_src/dependencies/tutorial004.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial004.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/dependencies/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
...and **FastAPI** will know what to do.
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ You saw that you can use dependencies with `yield` and have `try` blocks that ca
|
||||
|
||||
It might be tempting to raise an `HTTPException` or similar in the exit code, after the `yield`. But **it won't work**.
|
||||
|
||||
The exit code in dependencies with `yield` is executed *after* [Exception Handlers](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}. There's nothing catching exceptions thrown by your dependencies in the exit code (after the `yield`).
|
||||
The exit code in dependencies with `yield` is executed *after* the response is sent, so [Exception Handlers](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} will have already run. There's nothing catching exceptions thrown by your dependencies in the exit code (after the `yield`).
|
||||
|
||||
So, if you raise an `HTTPException` after the `yield`, the default (or any custom) exception handler that catches `HTTPException`s and returns an HTTP 400 response won't be there to catch that exception anymore.
|
||||
|
||||
@@ -138,9 +138,11 @@ participant tasks as Background tasks
|
||||
end
|
||||
dep ->> operation: Run dependency, e.g. DB session
|
||||
opt raise
|
||||
operation -->> handler: Raise HTTPException
|
||||
operation -->> dep: Raise HTTPException
|
||||
dep -->> handler: Auto forward exception
|
||||
handler -->> client: HTTP error response
|
||||
operation -->> dep: Raise other exception
|
||||
dep -->> handler: Auto forward exception
|
||||
end
|
||||
operation ->> client: Return response to client
|
||||
Note over client,operation: Response is already sent, can't change it anymore
|
||||
@@ -162,9 +164,9 @@ participant tasks as Background tasks
|
||||
After one of those responses is sent, no other response can be sent.
|
||||
|
||||
!!! tip
|
||||
This diagram shows `HTTPException`, but you could also raise any other exception for which you create a [Custom Exception Handler](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}. And that exception would be handled by that custom exception handler instead of the dependency exit code.
|
||||
This diagram shows `HTTPException`, but you could also raise any other exception for which you create a [Custom Exception Handler](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
|
||||
|
||||
But if you raise an exception that is not handled by the exception handlers, it will be handled by the exit code of the dependency.
|
||||
If you raise any exception, it will be passed to the dependencies with yield, including `HTTPException`, and then **again** to the exception handlers. If there's no exception handler for that exception, it will then be handled by the default internal `ServerErrorMiddleware`, returning a 500 HTTP status code, to let the client know that there was an error in the server.
|
||||
|
||||
## Context Managers
|
||||
|
||||
|
||||
@@ -31,9 +31,17 @@ Let's first focus on the dependency.
|
||||
|
||||
It is just a function that can take all the same parameters that a *path operation function* can take:
|
||||
|
||||
```Python hl_lines="8-9"
|
||||
{!../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="8-9"
|
||||
{!> ../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="6-7"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
That's it.
|
||||
|
||||
@@ -55,17 +63,33 @@ And then it just returns a `dict` containing those values.
|
||||
|
||||
### Import `Depends`
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
### Declare the dependency, in the "dependant"
|
||||
|
||||
The same way you use `Body`, `Query`, etc. with your *path operation function* parameters, use `Depends` with a new parameter:
|
||||
|
||||
```Python hl_lines="13 18"
|
||||
{!../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="13 18"
|
||||
{!> ../../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="11 16"
|
||||
{!> ../../../docs_src/dependencies/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
Although you use `Depends` in the parameters of your function the same way you use `Body`, `Query`, etc, `Depends` works a bit differently.
|
||||
|
||||
|
||||
@@ -6,25 +6,41 @@ They can be as **deep** as you need them to be.
|
||||
|
||||
**FastAPI** will take care of solving them.
|
||||
|
||||
### First dependency "dependable"
|
||||
## First dependency "dependable"
|
||||
|
||||
You could create a first dependency ("dependable") like:
|
||||
|
||||
```Python hl_lines="8-9"
|
||||
{!../../../docs_src/dependencies/tutorial005.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="8-9"
|
||||
{!> ../../../docs_src/dependencies/tutorial005.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="6-7"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
It declares an optional query parameter `q` as a `str`, and then it just returns it.
|
||||
|
||||
This is quite simple (not very useful), but will help us focus on how the sub-dependencies work.
|
||||
|
||||
### Second dependency, "dependable" and "dependant"
|
||||
## Second dependency, "dependable" and "dependant"
|
||||
|
||||
Then you can create another dependency function (a "dependable") that at the same time declares a dependency of its own (so it is a "dependant" too):
|
||||
|
||||
```Python hl_lines="13"
|
||||
{!../../../docs_src/dependencies/tutorial005.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="13"
|
||||
{!> ../../../docs_src/dependencies/tutorial005.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
Let's focus on the parameters declared:
|
||||
|
||||
@@ -33,13 +49,21 @@ Let's focus on the parameters declared:
|
||||
* It also declares an optional `last_query` cookie, as a `str`.
|
||||
* If the user didn't provide any query `q`, we use the last query used, which we saved to a cookie before.
|
||||
|
||||
### Use the dependency
|
||||
## Use the dependency
|
||||
|
||||
Then we can use the dependency with:
|
||||
|
||||
```Python hl_lines="21"
|
||||
{!../../../docs_src/dependencies/tutorial005.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="21"
|
||||
{!> ../../../docs_src/dependencies/tutorial005.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/dependencies/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
!!! info
|
||||
Notice that we are only declaring one dependency in the *path operation function*, the `query_or_cookie_extractor`.
|
||||
|
||||
@@ -20,9 +20,17 @@ You can use `jsonable_encoder` for that.
|
||||
|
||||
It receives an object, like a Pydantic model, and returns a JSON compatible version:
|
||||
|
||||
```Python hl_lines="5 22"
|
||||
{!../../../docs_src/encoder/tutorial001.py!}
|
||||
```
|
||||
=== "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!}
|
||||
```
|
||||
|
||||
In this example, it would convert the Pydantic model to a `dict`, and the `datetime` to a `str`.
|
||||
|
||||
|
||||
@@ -55,12 +55,28 @@ Here are some of the additional data types you can use:
|
||||
|
||||
Here's an example *path operation* with parameters using some of the above types.
|
||||
|
||||
```Python hl_lines="1 3 12-16"
|
||||
{!../../../docs_src/extra_data_types/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="1 3 12-16"
|
||||
{!> ../../../docs_src/extra_data_types/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="1 2 11-15"
|
||||
{!> ../../../docs_src/extra_data_types/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
Note that the parameters inside the function have their natural data type, and you can, for example, perform normal date manipulations, like:
|
||||
|
||||
```Python hl_lines="18-19"
|
||||
{!../../../docs_src/extra_data_types/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="18-19"
|
||||
{!> ../../../docs_src/extra_data_types/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="17-18"
|
||||
{!> ../../../docs_src/extra_data_types/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
@@ -17,9 +17,17 @@ This is especially the case for user models, because:
|
||||
|
||||
Here's a general idea of how the models could look like with their password fields and the places where they are used:
|
||||
|
||||
```Python hl_lines="9 11 16 22 24 29-30 33-35 40-41"
|
||||
{!../../../docs_src/extra_models/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="9 11 16 22 24 29-30 33-35 40-41"
|
||||
{!> ../../../docs_src/extra_models/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="7 9 14 20 22 27-28 31-33 38-39"
|
||||
{!> ../../../docs_src/extra_models/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
### About `**user_in.dict()`
|
||||
|
||||
@@ -150,9 +158,17 @@ All the data conversion, validation, documentation, etc. will still work as norm
|
||||
|
||||
That way, we can declare just the differences between the models (with plaintext `password`, with `hashed_password` and without password):
|
||||
|
||||
```Python hl_lines="9 15-16 19-20 23-24"
|
||||
{!../../../docs_src/extra_models/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="9 15-16 19-20 23-24"
|
||||
{!> ../../../docs_src/extra_models/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="7 13-14 17-18 21-22"
|
||||
{!> ../../../docs_src/extra_models/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
## `Union` or `anyOf`
|
||||
|
||||
@@ -165,19 +181,49 @@ To do that, use the standard Python type hint <a href="https://docs.python.org/3
|
||||
!!! note
|
||||
When defining a <a href="https://pydantic-docs.helpmanual.io/usage/types/#unions" class="external-link" target="_blank">`Union`</a>, include the most specific type first, followed by the less specific type. In the example below, the more specific `PlaneItem` comes before `CarItem` in `Union[PlaneItem, CarItem]`.
|
||||
|
||||
```Python hl_lines="1 14-15 18-20 33"
|
||||
{!../../../docs_src/extra_models/tutorial003.py!}
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="1 14-15 18-20 33"
|
||||
{!> ../../../docs_src/extra_models/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="1 14-15 18-20 33"
|
||||
{!> ../../../docs_src/extra_models/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
### `Union` in Python 3.10
|
||||
|
||||
In this example we pass `Union[PlaneItem, CarItem]` as the value of the argument `response_model`.
|
||||
|
||||
Because we are passing it as a **value to an argument** instead of putting it in a **type annotation**, we have to use `Union` even in Python 3.10.
|
||||
|
||||
If it was in a type annotation we could have used the vertical bar, as:
|
||||
|
||||
```Python
|
||||
some_variable: PlaneItem | CarItem
|
||||
```
|
||||
|
||||
But if we put that in `response_model=PlaneItem | CarItem` we would get an error, because Python would try to perform an **invalid operation** between `PlaneItem` and `CarItem` instead of interpreting that as a type annotation.
|
||||
|
||||
## List of models
|
||||
|
||||
The same way, you can declare responses of lists of objects.
|
||||
|
||||
For that, use the standard Python `typing.List`:
|
||||
For that, use the standard Python `typing.List` (or just `list` in Python 3.9 and above):
|
||||
|
||||
```Python hl_lines="1 20"
|
||||
{!../../../docs_src/extra_models/tutorial004.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="1 20"
|
||||
{!> ../../../docs_src/extra_models/tutorial004.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!> ../../../docs_src/extra_models/tutorial004_py39.py!}
|
||||
```
|
||||
|
||||
## Response with arbitrary `dict`
|
||||
|
||||
@@ -185,11 +231,19 @@ You can also declare a response using a plain arbitrary `dict`, declaring just t
|
||||
|
||||
This is useful if you don't know the valid field/attribute names (that would be needed for a Pydantic model) beforehand.
|
||||
|
||||
In this case, you can use `typing.Dict`:
|
||||
In this case, you can use `typing.Dict` (or just `dict` in Python 3.9 and above):
|
||||
|
||||
```Python hl_lines="1 8"
|
||||
{!../../../docs_src/extra_models/tutorial005.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="1 8"
|
||||
{!> ../../../docs_src/extra_models/tutorial005.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!> ../../../docs_src/extra_models/tutorial005_py39.py!}
|
||||
```
|
||||
|
||||
## Recap
|
||||
|
||||
|
||||
@@ -252,9 +252,7 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
|
||||
|
||||
### Re-use **FastAPI**'s exception handlers
|
||||
|
||||
You could also just want to use the exception somehow, but then use the same default exception handlers from **FastAPI**.
|
||||
|
||||
You can import and re-use the default exception handlers from `fastapi.exception_handlers`:
|
||||
If you want to use the exception along with the same default exception handlers from **FastAPI**, You can import and re-use the default exception handlers from `fastapi.exception_handlers`:
|
||||
|
||||
```Python hl_lines="2-5 15 21"
|
||||
{!../../../docs_src/handling_errors/tutorial006.py!}
|
||||
|
||||
@@ -6,9 +6,17 @@ You can define Header parameters the same way you define `Query`, `Path` and `Co
|
||||
|
||||
First import `Header`:
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!../../../docs_src/header_params/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../../docs_src/header_params/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../../docs_src/header_params/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
## Declare `Header` parameters
|
||||
|
||||
@@ -16,9 +24,17 @@ Then declare the header parameters using the same structure as with `Path`, `Que
|
||||
|
||||
The first value is the default value, you can pass all the extra validation or annotation parameters:
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../../docs_src/header_params/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/header_params/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/header_params/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
!!! note "Technical Details"
|
||||
`Header` is a "sister" class of `Path`, `Query` and `Cookie`. It also inherits from the same common `Param` class.
|
||||
@@ -44,14 +60,21 @@ So, you can use `user_agent` as you normally would in Python code, instead of ne
|
||||
|
||||
If for some reason you need to disable automatic conversion of underscores to hyphens, set the parameter `convert_underscores` of `Header` to `False`:
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!../../../docs_src/header_params/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/header_params/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../../docs_src/header_params/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
!!! warning
|
||||
Before setting `convert_underscores` to `False`, bear in mind that some HTTP proxies and servers disallow the usage of headers with underscores.
|
||||
|
||||
|
||||
## Duplicate headers
|
||||
|
||||
It is possible to receive duplicate headers. That means, the same header with multiple values.
|
||||
@@ -62,9 +85,23 @@ You will receive all the values from the duplicate header as a Python `list`.
|
||||
|
||||
For example, to declare a header of `X-Token` that can appear more than once, you can write:
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../../docs_src/header_params/tutorial003.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/header_params/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/header_params/tutorial003_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/header_params/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
If you communicate with that *path operation* sending two HTTP headers like:
|
||||
|
||||
|
||||
@@ -13,9 +13,23 @@ You can pass directly the `int` code, like `404`.
|
||||
|
||||
But if you don't remember what each number code is for, you can use the shortcut constants in `status`:
|
||||
|
||||
```Python hl_lines="3 17"
|
||||
{!../../../docs_src/path_operation_configuration/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="3 17"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="3 17"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial001_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="1 15"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
That status code will be used in the response and will be added to the OpenAPI schema.
|
||||
|
||||
@@ -28,21 +42,61 @@ That status code will be used in the response and will be added to the OpenAPI s
|
||||
|
||||
You can add tags to your *path operation*, pass the parameter `tags` with a `list` of `str` (commonly just one `str`):
|
||||
|
||||
```Python hl_lines="17 22 27"
|
||||
{!../../../docs_src/path_operation_configuration/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="17 22 27"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="17 22 27"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial002_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="15 20 25"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
They will be added to the OpenAPI schema and used by the automatic documentation interfaces:
|
||||
|
||||
<img src="/img/tutorial/path-operation-configuration/image01.png">
|
||||
|
||||
### Tags with Enums
|
||||
|
||||
If you have a big application, you might end up accumulating **several tags**, and you would want to make sure you always use the **same tag** for related *path operations*.
|
||||
|
||||
In these cases, it could make sense to store the tags in an `Enum`.
|
||||
|
||||
**FastAPI** supports that the same way as with plain strings:
|
||||
|
||||
```Python hl_lines="1 8-10 13 18"
|
||||
{!../../../docs_src/path_operation_configuration/tutorial002b.py!}
|
||||
```
|
||||
|
||||
## Summary and description
|
||||
|
||||
You can add a `summary` and `description`:
|
||||
|
||||
```Python hl_lines="20-21"
|
||||
{!../../../docs_src/path_operation_configuration/tutorial003.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="20-21"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="20-21"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial003_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="18-19"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
## Description from docstring
|
||||
|
||||
@@ -50,9 +104,23 @@ As descriptions tend to be long and cover multiple lines, you can declare the *p
|
||||
|
||||
You can write <a href="https://en.wikipedia.org/wiki/Markdown" class="external-link" target="_blank">Markdown</a> in the docstring, it will be interpreted and displayed correctly (taking into account docstring indentation).
|
||||
|
||||
```Python hl_lines="19-27"
|
||||
{!../../../docs_src/path_operation_configuration/tutorial004.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="19-27"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial004.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="19-27"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial004_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="17-25"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
It will be used in the interactive docs:
|
||||
|
||||
@@ -62,9 +130,23 @@ It will be used in the interactive docs:
|
||||
|
||||
You can specify the response description with the parameter `response_description`:
|
||||
|
||||
```Python hl_lines="21"
|
||||
{!../../../docs_src/path_operation_configuration/tutorial005.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="21"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial005.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="21"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial005_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
!!! info
|
||||
Notice that `response_description` refers specifically to the response, the `description` refers to the *path operation* in general.
|
||||
|
||||
@@ -6,9 +6,17 @@ The same way you can declare more validations and metadata for query parameters
|
||||
|
||||
First, import `Path` from `fastapi`:
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!../../../docs_src/path_params_numeric_validations/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
## Declare metadata
|
||||
|
||||
@@ -16,13 +24,21 @@ You can declare all the same parameters as for `Query`.
|
||||
|
||||
For example, to declare a `title` metadata value for the path parameter `item_id` you can type:
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!../../../docs_src/path_params_numeric_validations/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
!!! note
|
||||
A path parameter is always required as it has to be part of the path.
|
||||
|
||||
|
||||
So, you should declare it with `...` to mark it as required.
|
||||
|
||||
Nevertheless, even if you declared it with `None` or set a default value, it would not affect anything, it would still be always required.
|
||||
|
||||
@@ -4,11 +4,19 @@
|
||||
|
||||
Let's take this application as example:
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../../docs_src/query_params_str_validations/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
The query parameter `q` is of type `Optional[str]`, that means that it's of type `str` but could also be `None`, and indeed, the default value is `None`, so FastAPI will know it's not required.
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
The query parameter `q` is of type `Optional[str]` (or `str | None` in Python 3.10), that means that it's of type `str` but could also be `None`, and indeed, the default value is `None`, so FastAPI will know it's not required.
|
||||
|
||||
!!! note
|
||||
FastAPI will know that the value of `q` is not required because of the default value `= None`.
|
||||
@@ -23,17 +31,33 @@ We are going to enforce that even though `q` is optional, whenever it is provide
|
||||
|
||||
To achieve that, first import `Query` from `fastapi`:
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!../../../docs_src/query_params_str_validations/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
## Use `Query` as the default value
|
||||
|
||||
And now use it as the default value of your parameter, setting the parameter `max_length` to 50:
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../../docs_src/query_params_str_validations/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
As we have to replace the default value `None` with `Query(None)`, the first parameter to `Query` serves the same purpose of defining that default value.
|
||||
|
||||
@@ -49,10 +73,22 @@ q: Optional[str] = Query(None)
|
||||
q: Optional[str] = None
|
||||
```
|
||||
|
||||
And in Python 3.10 and above:
|
||||
|
||||
```Python
|
||||
q: str | None = Query(None)
|
||||
```
|
||||
|
||||
...makes the parameter optional, the same as:
|
||||
|
||||
```Python
|
||||
q: str | None = None
|
||||
```
|
||||
|
||||
But it declares it explicitly as being a query parameter.
|
||||
|
||||
!!! info
|
||||
Have in mind that FastAPI cares about the part:
|
||||
Have in mind that the most important part to make a parameter optional is the part:
|
||||
|
||||
```Python
|
||||
= None
|
||||
@@ -64,9 +100,9 @@ But it declares it explicitly as being a query parameter.
|
||||
= Query(None)
|
||||
```
|
||||
|
||||
and will use that `None` to detect that the query parameter is not required.
|
||||
as it will use that `None` as the default value, and that way make the parameter **not required**.
|
||||
|
||||
The `Optional` part is only to allow your editor to provide better support.
|
||||
The `Optional` part allows your editor to provide better support, but it is not what tells FastAPI that this parameter is not required.
|
||||
|
||||
Then, we can pass more parameters to `Query`. In this case, the `max_length` parameter that applies to strings:
|
||||
|
||||
@@ -80,17 +116,33 @@ This will validate the data, show a clear error when the data is not valid, and
|
||||
|
||||
You can also add a parameter `min_length`:
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../../docs_src/query_params_str_validations/tutorial003.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
## Add regular expressions
|
||||
|
||||
You can define a <abbr title="A regular expression, regex or regexp is a sequence of characters that define a search pattern for strings.">regular expression</abbr> that the parameter should match:
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!../../../docs_src/query_params_str_validations/tutorial004.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial004.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
This specific regular expression checks that the received parameter value:
|
||||
|
||||
@@ -152,9 +204,23 @@ When you define a query parameter explicitly with `Query` you can also declare i
|
||||
|
||||
For example, to declare a query parameter `q` that can appear multiple times in the URL, you can write:
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../../docs_src/query_params_str_validations/tutorial011.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial011.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial011_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial011_py310.py!}
|
||||
```
|
||||
|
||||
Then, with a URL like:
|
||||
|
||||
@@ -186,9 +252,17 @@ The interactive API docs will update accordingly, to allow multiple values:
|
||||
|
||||
And you can also define a default `list` of values if none are provided:
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../../docs_src/query_params_str_validations/tutorial012.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial012.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial012_py39.py!}
|
||||
```
|
||||
|
||||
If you go to:
|
||||
|
||||
@@ -209,7 +283,7 @@ the default of `q` will be: `["foo", "bar"]` and your response will be:
|
||||
|
||||
#### Using `list`
|
||||
|
||||
You can also use `list` directly instead of `List[str]`:
|
||||
You can also use `list` directly instead of `List[str]` (or `list[str]` in Python 3.9+):
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!../../../docs_src/query_params_str_validations/tutorial013.py!}
|
||||
@@ -233,15 +307,31 @@ That information will be included in the generated OpenAPI and used by the docum
|
||||
|
||||
You can add a `title`:
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!../../../docs_src/query_params_str_validations/tutorial007.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial007.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial007_py310.py!}
|
||||
```
|
||||
|
||||
And a `description`:
|
||||
|
||||
```Python hl_lines="13"
|
||||
{!../../../docs_src/query_params_str_validations/tutorial008.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="13"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial008.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial008_py310.py!}
|
||||
```
|
||||
|
||||
## Alias parameters
|
||||
|
||||
@@ -261,9 +351,17 @@ But you still need it to be exactly `item-query`...
|
||||
|
||||
Then you can declare an `alias`, and that alias is what will be used to find the parameter value:
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../../docs_src/query_params_str_validations/tutorial009.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial009.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial009_py310.py!}
|
||||
```
|
||||
|
||||
## Deprecating parameters
|
||||
|
||||
@@ -273,14 +371,38 @@ You have to leave it there a while because there are clients using it, but you w
|
||||
|
||||
Then pass the parameter `deprecated=True` to `Query`:
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!../../../docs_src/query_params_str_validations/tutorial010.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial010.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial010_py310.py!}
|
||||
```
|
||||
|
||||
The docs will show it like this:
|
||||
|
||||
<img src="/img/tutorial/query-params-str-validations/image01.png">
|
||||
|
||||
## Exclude from OpenAPI
|
||||
|
||||
To exclude a query parameter from the generated OpenAPI schema (and thus, from the automatic documentation systems), set the parameter `include_in_schema` of `Query` to `False`:
|
||||
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial014.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/query_params_str_validations/tutorial014_py310.py!}
|
||||
```
|
||||
|
||||
## Recap
|
||||
|
||||
You can declare additional validations and metadata for your parameters.
|
||||
|
||||
@@ -63,27 +63,38 @@ The parameter values in your function will be:
|
||||
|
||||
The same way, you can declare optional query parameters, by setting their default to `None`:
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../../docs_src/query_params/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/query_params/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/query_params/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
In this case, the function parameter `q` will be optional, and will be `None` by default.
|
||||
|
||||
!!! check
|
||||
Also notice that **FastAPI** is smart enough to notice that the path parameter `item_id` is a path parameter and `q` is not, so, it's a query parameter.
|
||||
|
||||
!!! note
|
||||
FastAPI will know that `q` is optional because of the `= None`.
|
||||
|
||||
The `Optional` in `Optional[str]` is not used by FastAPI (FastAPI will only use the `str` part), but the `Optional[str]` will let your editor help you finding errors in your code.
|
||||
|
||||
## Query parameter type conversion
|
||||
|
||||
You can also declare `bool` types, and they will be converted:
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../../docs_src/query_params/tutorial003.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/query_params/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/query_params/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
In this case, if you go to:
|
||||
|
||||
@@ -126,9 +137,17 @@ And you don't have to declare them in any specific order.
|
||||
|
||||
They will be detected by name:
|
||||
|
||||
```Python hl_lines="8 10"
|
||||
{!../../../docs_src/query_params/tutorial004.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="8 10"
|
||||
{!> ../../../docs_src/query_params/tutorial004.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="6 8"
|
||||
{!> ../../../docs_src/query_params/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
## Required query parameters
|
||||
|
||||
@@ -184,9 +203,17 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
|
||||
|
||||
And of course, you can define some parameters as required, some as having a default value, and some entirely optional:
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!../../../docs_src/query_params/tutorial006.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/query_params/tutorial006.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../../docs_src/query_params/tutorial006_py310.py!}
|
||||
```
|
||||
|
||||
In this case, there are 3 query parameters:
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ Import `File` and `UploadFile` from `fastapi`:
|
||||
{!../../../docs_src/request_files/tutorial001.py!}
|
||||
```
|
||||
|
||||
## Define `File` parameters
|
||||
## Define `File` Parameters
|
||||
|
||||
Create file parameters the same way you would for `Body` or `Form`:
|
||||
|
||||
@@ -41,9 +41,9 @@ Have in mind that this means that the whole contents will be stored in memory. T
|
||||
|
||||
But there are several cases in which you might benefit from using `UploadFile`.
|
||||
|
||||
## `File` parameters with `UploadFile`
|
||||
## File Parameters with `UploadFile`
|
||||
|
||||
Define a `File` parameter with a type of `UploadFile`:
|
||||
Define a file parameter with a type of `UploadFile`:
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!../../../docs_src/request_files/tutorial001.py!}
|
||||
@@ -51,6 +51,7 @@ Define a `File` parameter with a type of `UploadFile`:
|
||||
|
||||
Using `UploadFile` has several advantages over `bytes`:
|
||||
|
||||
* You don't have to use `File()` in the default value of the parameter.
|
||||
* It uses a "spooled" file:
|
||||
* A file stored in memory up to a maximum size limit, and after passing this limit it will be stored in disk.
|
||||
* This means that it will work well for large files like images, videos, large binaries, etc. without consuming all the memory.
|
||||
@@ -113,17 +114,49 @@ The way HTML forms (`<form></form>`) sends the data to the server normally uses
|
||||
|
||||
This is not a limitation of **FastAPI**, it's part of the HTTP protocol.
|
||||
|
||||
## Multiple file uploads
|
||||
## Optional File Upload
|
||||
|
||||
You can make a file optional by using standard type annotations and setting a default value of `None`:
|
||||
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="9 17"
|
||||
{!> ../../../docs_src/request_files/tutorial001_02.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="7 14"
|
||||
{!> ../../../docs_src/request_files/tutorial001_02_py310.py!}
|
||||
```
|
||||
|
||||
## `UploadFile` with Additional Metadata
|
||||
|
||||
You can also use `File()` with `UploadFile`, for example, to set additional metadata:
|
||||
|
||||
```Python hl_lines="13"
|
||||
{!../../../docs_src/request_files/tutorial001_03.py!}
|
||||
```
|
||||
|
||||
## Multiple File Uploads
|
||||
|
||||
It's possible to upload several files at the same time.
|
||||
|
||||
They would be associated to the same "form field" sent using "form data".
|
||||
|
||||
To use that, declare a `List` of `bytes` or `UploadFile`:
|
||||
To use that, declare a list of `bytes` or `UploadFile`:
|
||||
|
||||
```Python hl_lines="10 15"
|
||||
{!../../../docs_src/request_files/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="10 15"
|
||||
{!> ../../../docs_src/request_files/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="8 13"
|
||||
{!> ../../../docs_src/request_files/tutorial002_py39.py!}
|
||||
```
|
||||
|
||||
You will receive, as declared, a `list` of `bytes` or `UploadFile`s.
|
||||
|
||||
@@ -132,6 +165,22 @@ You will receive, as declared, a `list` of `bytes` or `UploadFile`s.
|
||||
|
||||
**FastAPI** provides the same `starlette.responses` as `fastapi.responses` just as a convenience for you, the developer. But most of the available responses come directly from Starlette.
|
||||
|
||||
### Multiple File Uploads with Additional Metadata
|
||||
|
||||
And the same way as before, you can use `File()` to set additional parameters, even for `UploadFile`:
|
||||
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!> ../../../docs_src/request_files/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="16"
|
||||
{!> ../../../docs_src/request_files/tutorial003_py39.py!}
|
||||
```
|
||||
|
||||
## Recap
|
||||
|
||||
Use `File` to declare files to be uploaded as input parameters (as form data).
|
||||
Use `File`, `bytes`, and `UploadFile` to declare files to be uploaded in the request, sent as form data.
|
||||
|
||||
@@ -8,9 +8,23 @@ You can declare the model used for the response with the parameter `response_mod
|
||||
* `@app.delete()`
|
||||
* etc.
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!../../../docs_src/response_model/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/response_model/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/response_model/tutorial001_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="15"
|
||||
{!> ../../../docs_src/response_model/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
!!! note
|
||||
Notice that `response_model` is a parameter of the "decorator" method (`get`, `post`, etc). Not of your *path operation function*, like all the parameters and body.
|
||||
@@ -35,15 +49,31 @@ But most importantly:
|
||||
|
||||
Here we are declaring a `UserIn` model, it will contain a plaintext password:
|
||||
|
||||
```Python hl_lines="9 11"
|
||||
{!../../../docs_src/response_model/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="9 11"
|
||||
{!> ../../../docs_src/response_model/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="7 9"
|
||||
{!> ../../../docs_src/response_model/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
And we are using this model to declare our input and the same model to declare our output:
|
||||
|
||||
```Python hl_lines="17-18"
|
||||
{!../../../docs_src/response_model/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="17-18"
|
||||
{!> ../../../docs_src/response_model/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="15-16"
|
||||
{!> ../../../docs_src/response_model/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
Now, whenever a browser is creating a user with a password, the API will return the same password in the response.
|
||||
|
||||
@@ -58,21 +88,45 @@ But if we use the same model for another *path operation*, we could be sending o
|
||||
|
||||
We can instead create an input model with the plaintext password and an output model without it:
|
||||
|
||||
```Python hl_lines="9 11 16"
|
||||
{!../../../docs_src/response_model/tutorial003.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="9 11 16"
|
||||
{!> ../../../docs_src/response_model/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="7 9 14"
|
||||
{!> ../../../docs_src/response_model/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
Here, even though our *path operation function* is returning the same input user that contains the password:
|
||||
|
||||
```Python hl_lines="24"
|
||||
{!../../../docs_src/response_model/tutorial003.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="24"
|
||||
{!> ../../../docs_src/response_model/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="22"
|
||||
{!> ../../../docs_src/response_model/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
...we declared the `response_model` to be our model `UserOut`, that doesn't include the password:
|
||||
|
||||
```Python hl_lines="22"
|
||||
{!../../../docs_src/response_model/tutorial003.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="22"
|
||||
{!> ../../../docs_src/response_model/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/response_model/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
So, **FastAPI** will take care of filtering out all the data that is not declared in the output model (using Pydantic).
|
||||
|
||||
@@ -90,9 +144,23 @@ And both models will be used for the interactive API documentation:
|
||||
|
||||
Your response model could have default values, like:
|
||||
|
||||
```Python hl_lines="11 13-14"
|
||||
{!../../../docs_src/response_model/tutorial004.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="11 13-14"
|
||||
{!> ../../../docs_src/response_model/tutorial004.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="11 13-14"
|
||||
{!> ../../../docs_src/response_model/tutorial004_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="9 11-12"
|
||||
{!> ../../../docs_src/response_model/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
* `description: Optional[str] = None` has a default of `None`.
|
||||
* `tax: float = 10.5` has a default of `10.5`.
|
||||
@@ -106,9 +174,23 @@ For example, if you have models with many optional attributes in a NoSQL databas
|
||||
|
||||
You can set the *path operation decorator* parameter `response_model_exclude_unset=True`:
|
||||
|
||||
```Python hl_lines="24"
|
||||
{!../../../docs_src/response_model/tutorial004.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="24"
|
||||
{!> ../../../docs_src/response_model/tutorial004.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="24"
|
||||
{!> ../../../docs_src/response_model/tutorial004_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="22"
|
||||
{!> ../../../docs_src/response_model/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
and those default values won't be included in the response, only the values actually set.
|
||||
|
||||
@@ -185,9 +267,17 @@ This can be used as a quick shortcut if you have only one Pydantic model and wan
|
||||
|
||||
This also applies to `response_model_by_alias` that works similarly.
|
||||
|
||||
```Python hl_lines="31 37"
|
||||
{!../../../docs_src/response_model/tutorial005.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="31 37"
|
||||
{!> ../../../docs_src/response_model/tutorial005.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="29 35"
|
||||
{!> ../../../docs_src/response_model/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
The syntax `{"name", "description"}` creates a `set` with those two values.
|
||||
@@ -198,9 +288,17 @@ This can be used as a quick shortcut if you have only one Pydantic model and wan
|
||||
|
||||
If you forget to use a `set` and use a `list` or `tuple` instead, FastAPI will still convert it to a `set` and it will work correctly:
|
||||
|
||||
```Python hl_lines="31 37"
|
||||
{!../../../docs_src/response_model/tutorial006.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="31 37"
|
||||
{!> ../../../docs_src/response_model/tutorial006.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="29 35"
|
||||
{!> ../../../docs_src/response_model/tutorial006_py310.py!}
|
||||
```
|
||||
|
||||
## Recap
|
||||
|
||||
|
||||
@@ -8,9 +8,17 @@ Here are several ways to do it.
|
||||
|
||||
You can declare an `example` for a Pydantic model using `Config` and `schema_extra`, as described in <a href="https://pydantic-docs.helpmanual.io/usage/schema/#schema-customization" class="external-link" target="_blank">Pydantic's docs: Schema customization</a>:
|
||||
|
||||
```Python hl_lines="15-23"
|
||||
{!../../../docs_src/schema_extra_example/tutorial001.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="15-23"
|
||||
{!> ../../../docs_src/schema_extra_example/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="13-21"
|
||||
{!> ../../../docs_src/schema_extra_example/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
That extra info will be added as-is to the output **JSON Schema** for that model, and it will be used in the API docs.
|
||||
|
||||
@@ -25,9 +33,17 @@ When using `Field()` with Pydantic models, you can also declare extra info for t
|
||||
|
||||
You can use this to add `example` for each field:
|
||||
|
||||
```Python hl_lines="4 10-13"
|
||||
{!../../../docs_src/schema_extra_example/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="4 10-13"
|
||||
{!> ../../../docs_src/schema_extra_example/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="2 8-11"
|
||||
{!> ../../../docs_src/schema_extra_example/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
!!! warning
|
||||
Keep in mind that those extra arguments passed won't add any validation, only extra information, for documentation purposes.
|
||||
@@ -50,9 +66,17 @@ you can also declare a data `example` or a group of `examples` with additional i
|
||||
|
||||
Here we pass an `example` of the data expected in `Body()`:
|
||||
|
||||
```Python hl_lines="21-26"
|
||||
{!../../../docs_src/schema_extra_example/tutorial003.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="21-26"
|
||||
{!> ../../../docs_src/schema_extra_example/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="19-24"
|
||||
{!> ../../../docs_src/schema_extra_example/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
### Example in the docs UI
|
||||
|
||||
@@ -73,9 +97,17 @@ Each specific example `dict` in the `examples` can contain:
|
||||
* `value`: This is the actual example shown, e.g. a `dict`.
|
||||
* `externalValue`: alternative to `value`, a URL pointing to the example. Although this might not be supported by as many tools as `value`.
|
||||
|
||||
```Python hl_lines="22-48"
|
||||
{!../../../docs_src/schema_extra_example/tutorial004.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="22-48"
|
||||
{!> ../../../docs_src/schema_extra_example/tutorial004.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="20-46"
|
||||
{!> ../../../docs_src/schema_extra_example/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
### Examples in the docs UI
|
||||
|
||||
|
||||
@@ -16,9 +16,17 @@ First, let's create a Pydantic user model.
|
||||
|
||||
The same way we use Pydantic to declare bodies, we can use it anywhere else:
|
||||
|
||||
```Python hl_lines="5 12-16"
|
||||
{!../../../docs_src/security/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="5 12-16"
|
||||
{!> ../../../docs_src/security/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="3 10-14"
|
||||
{!> ../../../docs_src/security/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
## Create a `get_current_user` dependency
|
||||
|
||||
@@ -30,25 +38,49 @@ Remember that dependencies can have sub-dependencies?
|
||||
|
||||
The same as we were doing before in the *path operation* directly, our new dependency `get_current_user` will receive a `token` as a `str` from the sub-dependency `oauth2_scheme`:
|
||||
|
||||
```Python hl_lines="25"
|
||||
{!../../../docs_src/security/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="25"
|
||||
{!> ../../../docs_src/security/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="23"
|
||||
{!> ../../../docs_src/security/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
## Get the user
|
||||
|
||||
`get_current_user` will use a (fake) utility function we created, that takes a token as a `str` and returns our Pydantic `User` model:
|
||||
|
||||
```Python hl_lines="19-22 26-27"
|
||||
{!../../../docs_src/security/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="19-22 26-27"
|
||||
{!> ../../../docs_src/security/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="17-20 24-25"
|
||||
{!> ../../../docs_src/security/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
## Inject the current user
|
||||
|
||||
So now we can use the same `Depends` with our `get_current_user` in the *path operation*:
|
||||
|
||||
```Python hl_lines="31"
|
||||
{!../../../docs_src/security/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="31"
|
||||
{!> ../../../docs_src/security/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="29"
|
||||
{!> ../../../docs_src/security/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
Notice that we declare the type of `current_user` as the Pydantic model `User`.
|
||||
|
||||
@@ -64,7 +96,6 @@ This will help us inside of the function with all the completion and type checks
|
||||
|
||||
We are not restricted to having only one dependency that can return that type of data.
|
||||
|
||||
|
||||
## Other models
|
||||
|
||||
You can now get the current user directly in the *path operation functions* and deal with the security mechanisms at the **Dependency Injection** level, using `Depends`.
|
||||
@@ -81,7 +112,6 @@ You actually don't have users that log in to your application but robots, bots,
|
||||
|
||||
Just use any kind of model, any kind of class, any kind of database that you need for your application. **FastAPI** has you covered with the dependency injection system.
|
||||
|
||||
|
||||
## Code size
|
||||
|
||||
This example might seem verbose. Have in mind that we are mixing security, data models, utility functions and *path operations* in the same file.
|
||||
@@ -98,9 +128,17 @@ And all of them (or any portion of them that you want) can take the advantage of
|
||||
|
||||
And all these thousands of *path operations* can be as small as 3 lines:
|
||||
|
||||
```Python hl_lines="30-32"
|
||||
{!../../../docs_src/security/tutorial002.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="30-32"
|
||||
{!> ../../../docs_src/security/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="28-30"
|
||||
{!> ../../../docs_src/security/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
## Recap
|
||||
|
||||
|
||||
@@ -109,9 +109,17 @@ And another utility to verify if a received password matches the hash stored.
|
||||
|
||||
And another one to authenticate and return a user.
|
||||
|
||||
```Python hl_lines="7 48 55-56 59-60 69-75"
|
||||
{!../../../docs_src/security/tutorial004.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="7 48 55-56 59-60 69-75"
|
||||
{!> ../../../docs_src/security/tutorial004.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="6 47 54-55 58-59 68-74"
|
||||
{!> ../../../docs_src/security/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
!!! note
|
||||
If you check the new (fake) database `fake_users_db`, you will see how the hashed password looks like now: `"$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW"`.
|
||||
@@ -144,9 +152,17 @@ Define a Pydantic Model that will be used in the token endpoint for the response
|
||||
|
||||
Create a utility function to generate a new access token.
|
||||
|
||||
```Python hl_lines="6 12-14 28-30 78-86"
|
||||
{!../../../docs_src/security/tutorial004.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="6 12-14 28-30 78-86"
|
||||
{!> ../../../docs_src/security/tutorial004.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="5 11-13 27-29 77-85"
|
||||
{!> ../../../docs_src/security/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
## Update the dependencies
|
||||
|
||||
@@ -156,9 +172,17 @@ Decode the received token, verify it, and return the current user.
|
||||
|
||||
If the token is invalid, return an HTTP error right away.
|
||||
|
||||
```Python hl_lines="89-106"
|
||||
{!../../../docs_src/security/tutorial004.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="89-106"
|
||||
{!> ../../../docs_src/security/tutorial004.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="88-105"
|
||||
{!> ../../../docs_src/security/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
## Update the `/token` *path operation*
|
||||
|
||||
@@ -166,9 +190,17 @@ Create a `timedelta` with the expiration time of the token.
|
||||
|
||||
Create a real JWT access token and return it.
|
||||
|
||||
```Python hl_lines="115-128"
|
||||
{!../../../docs_src/security/tutorial004.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="115-128"
|
||||
{!> ../../../docs_src/security/tutorial004.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="114-127"
|
||||
{!> ../../../docs_src/security/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
### Technical details about the JWT "subject" `sub`
|
||||
|
||||
|
||||
@@ -49,9 +49,17 @@ Now let's use the utilities provided by **FastAPI** to handle this.
|
||||
|
||||
First, import `OAuth2PasswordRequestForm`, and use it as a dependency with `Depends` in the *path operation* for `/token`:
|
||||
|
||||
```Python hl_lines="4 76"
|
||||
{!../../../docs_src/security/tutorial003.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="4 76"
|
||||
{!> ../../../docs_src/security/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="2 74"
|
||||
{!> ../../../docs_src/security/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
`OAuth2PasswordRequestForm` is a class dependency that declares a form body with:
|
||||
|
||||
@@ -90,9 +98,17 @@ If there is no such user, we return an error saying "incorrect username or passw
|
||||
|
||||
For the error, we use the exception `HTTPException`:
|
||||
|
||||
```Python hl_lines="3 77-79"
|
||||
{!../../../docs_src/security/tutorial003.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="3 77-79"
|
||||
{!> ../../../docs_src/security/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="1 75-77"
|
||||
{!> ../../../docs_src/security/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
### Check the password
|
||||
|
||||
@@ -118,9 +134,17 @@ If your database is stolen, the thief won't have your users' plaintext passwords
|
||||
|
||||
So, the thief won't be able to try to use those same passwords in another system (as many users use the same password everywhere, this would be dangerous).
|
||||
|
||||
```Python hl_lines="80-83"
|
||||
{!../../../docs_src/security/tutorial003.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="80-83"
|
||||
{!> ../../../docs_src/security/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="78-81"
|
||||
{!> ../../../docs_src/security/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
#### About `**user_dict`
|
||||
|
||||
@@ -156,9 +180,17 @@ For this simple example, we are going to just be completely insecure and return
|
||||
|
||||
But for now, let's focus on the specific details we need.
|
||||
|
||||
```Python hl_lines="85"
|
||||
{!../../../docs_src/security/tutorial003.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="85"
|
||||
{!> ../../../docs_src/security/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="83"
|
||||
{!> ../../../docs_src/security/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
By the spec, you should return a JSON with an `access_token` and a `token_type`, the same as in this example.
|
||||
@@ -181,9 +213,17 @@ Both of these dependencies will just return an HTTP error if the user doesn't ex
|
||||
|
||||
So, in our endpoint, we will only get a user if the user exists, was correctly authenticated, and is active:
|
||||
|
||||
```Python hl_lines="58-67 69-72 90"
|
||||
{!../../../docs_src/security/tutorial003.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="58-66 69-72 90"
|
||||
{!> ../../../docs_src/security/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="55-64 67-70 88"
|
||||
{!> ../../../docs_src/security/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
!!! info
|
||||
The additional header `WWW-Authenticate` with value `Bearer` we are returning here is also part of the spec.
|
||||
|
||||
@@ -248,9 +248,23 @@ So, the user will also have a `password` when creating it.
|
||||
|
||||
But for security, the `password` won't be in other Pydantic *models*, for example, it won't be sent from the API when reading a user.
|
||||
|
||||
```Python hl_lines="3 6-8 11-12 23-24 27-28"
|
||||
{!../../../docs_src/sql_databases/sql_app/schemas.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="3 6-8 11-12 23-24 27-28"
|
||||
{!> ../../../docs_src/sql_databases/sql_app/schemas.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="3 6-8 11-12 23-24 27-28"
|
||||
{!> ../../../docs_src/sql_databases/sql_app_py39/schemas.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="1 4-6 9-10 21-22 25-26"
|
||||
{!> ../../../docs_src/sql_databases/sql_app_py310/schemas.py!}
|
||||
```
|
||||
|
||||
#### SQLAlchemy style and Pydantic style
|
||||
|
||||
@@ -278,9 +292,23 @@ The same way, when reading a user, we can now declare that `items` will contain
|
||||
|
||||
Not only the IDs of those items, but all the data that we defined in the Pydantic *model* for reading items: `Item`.
|
||||
|
||||
```Python hl_lines="15-17 31-34"
|
||||
{!../../../docs_src/sql_databases/sql_app/schemas.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="15-17 31-34"
|
||||
{!> ../../../docs_src/sql_databases/sql_app/schemas.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="15-17 31-34"
|
||||
{!> ../../../docs_src/sql_databases/sql_app_py39/schemas.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="13-15 29-32"
|
||||
{!> ../../../docs_src/sql_databases/sql_app_py310/schemas.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
Notice that the `User`, the Pydantic *model* that will be used when reading a user (returning it from the API) doesn't include the `password`.
|
||||
@@ -293,9 +321,23 @@ This <a href="https://pydantic-docs.helpmanual.io/#config" class="external-link"
|
||||
|
||||
In the `Config` class, set the attribute `orm_mode = True`.
|
||||
|
||||
```Python hl_lines="15 19-20 31 36-37"
|
||||
{!../../../docs_src/sql_databases/sql_app/schemas.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="15 19-20 31 36-37"
|
||||
{!> ../../../docs_src/sql_databases/sql_app/schemas.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="15 19-20 31 36-37"
|
||||
{!> ../../../docs_src/sql_databases/sql_app_py39/schemas.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="13 17-18 29 34-35"
|
||||
{!> ../../../docs_src/sql_databases/sql_app_py310/schemas.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
Notice it's assigning a value with `=`, like:
|
||||
@@ -425,9 +467,17 @@ And now in the file `sql_app/main.py` let's integrate and use all the other part
|
||||
|
||||
In a very simplistic way create the database tables:
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../../docs_src/sql_databases/sql_app/main.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/sql_databases/sql_app/main.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/sql_databases/sql_app_py39/main.py!}
|
||||
```
|
||||
|
||||
#### Alembic Note
|
||||
|
||||
@@ -441,7 +491,7 @@ You can find an example of Alembic in a FastAPI project in the templates from [P
|
||||
|
||||
### Create a dependency
|
||||
|
||||
Now use the `SessionLocal` class we created in the `sql_app/databases.py` file to create a dependency.
|
||||
Now use the `SessionLocal` class we created in the `sql_app/database.py` file to create a dependency.
|
||||
|
||||
We need to have an independent database session/connection (`SessionLocal`) per request, use the same session through all the request and then close it after the request is finished.
|
||||
|
||||
@@ -451,9 +501,17 @@ For that, we will create a new dependency with `yield`, as explained before in t
|
||||
|
||||
Our dependency will create a new SQLAlchemy `SessionLocal` that will be used in a single request, and then close it once the request is finished.
|
||||
|
||||
```Python hl_lines="15-20"
|
||||
{!../../../docs_src/sql_databases/sql_app/main.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="15-20"
|
||||
{!> ../../../docs_src/sql_databases/sql_app/main.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="13-18"
|
||||
{!> ../../../docs_src/sql_databases/sql_app_py39/main.py!}
|
||||
```
|
||||
|
||||
!!! info
|
||||
We put the creation of the `SessionLocal()` and handling of the requests in a `try` block.
|
||||
@@ -468,9 +526,17 @@ And then, when using the dependency in a *path operation function*, we declare i
|
||||
|
||||
This will then give us better editor support inside the *path operation function*, because the editor will know that the `db` parameter is of type `Session`:
|
||||
|
||||
```Python hl_lines="24 32 38 47 53"
|
||||
{!../../../docs_src/sql_databases/sql_app/main.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="24 32 38 47 53"
|
||||
{!> ../../../docs_src/sql_databases/sql_app/main.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="22 30 36 45 51"
|
||||
{!> ../../../docs_src/sql_databases/sql_app_py39/main.py!}
|
||||
```
|
||||
|
||||
!!! info "Technical Details"
|
||||
The parameter `db` is actually of type `SessionLocal`, but this class (created with `sessionmaker()`) is a "proxy" of a SQLAlchemy `Session`, so, the editor doesn't really know what methods are provided.
|
||||
@@ -481,9 +547,17 @@ This will then give us better editor support inside the *path operation function
|
||||
|
||||
Now, finally, here's the standard **FastAPI** *path operations* code.
|
||||
|
||||
```Python hl_lines="23-28 31-34 37-42 45-49 52-55"
|
||||
{!../../../docs_src/sql_databases/sql_app/main.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="23-28 31-34 37-42 45-49 52-55"
|
||||
{!> ../../../docs_src/sql_databases/sql_app/main.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="21-26 29-32 35-40 43-47 50-53"
|
||||
{!> ../../../docs_src/sql_databases/sql_app_py39/main.py!}
|
||||
```
|
||||
|
||||
We are creating the database session before each request in the dependency with `yield`, and then closing it afterwards.
|
||||
|
||||
@@ -566,9 +640,23 @@ For example, in a background task worker with <a href="https://docs.celeryprojec
|
||||
|
||||
* `sql_app/schemas.py`:
|
||||
|
||||
```Python
|
||||
{!../../../docs_src/sql_databases/sql_app/schemas.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python
|
||||
{!> ../../../docs_src/sql_databases/sql_app/schemas.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python
|
||||
{!> ../../../docs_src/sql_databases/sql_app_py39/schemas.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python
|
||||
{!> ../../../docs_src/sql_databases/sql_app_py310/schemas.py!}
|
||||
```
|
||||
|
||||
* `sql_app/crud.py`:
|
||||
|
||||
@@ -578,9 +666,17 @@ For example, in a background task worker with <a href="https://docs.celeryprojec
|
||||
|
||||
* `sql_app/main.py`:
|
||||
|
||||
```Python
|
||||
{!../../../docs_src/sql_databases/sql_app/main.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python
|
||||
{!> ../../../docs_src/sql_databases/sql_app/main.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python
|
||||
{!> ../../../docs_src/sql_databases/sql_app_py39/main.py!}
|
||||
```
|
||||
|
||||
## Check it
|
||||
|
||||
@@ -629,9 +725,17 @@ A "middleware" is basically a function that is always executed for each request,
|
||||
|
||||
The middleware we'll add (just a function) will create a new SQLAlchemy `SessionLocal` for each request, add it to the request and then close it once the request is finished.
|
||||
|
||||
```Python hl_lines="14-22"
|
||||
{!../../../docs_src/sql_databases/sql_app/alt_main.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python hl_lines="14-22"
|
||||
{!> ../../../docs_src/sql_databases/sql_app/alt_main.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9 and above"
|
||||
|
||||
```Python hl_lines="12-20"
|
||||
{!> ../../../docs_src/sql_databases/sql_app_py39/alt_main.py!}
|
||||
```
|
||||
|
||||
!!! info
|
||||
We put the creation of the `SessionLocal()` and handling of the requests in a `try` block.
|
||||
|
||||
@@ -10,7 +10,7 @@ With it, you can use <a href="https://docs.pytest.org/" class="external-link" ta
|
||||
|
||||
Import `TestClient`.
|
||||
|
||||
Create a `TestClient` passing to it your **FastAPI** application.
|
||||
Create a `TestClient` by passing your **FastAPI** application to it.
|
||||
|
||||
Create functions with a name that starts with `test_` (this is standard `pytest` conventions).
|
||||
|
||||
@@ -65,7 +65,7 @@ Now let's extend this example and add more details to see how to test different
|
||||
|
||||
### Extended **FastAPI** app file
|
||||
|
||||
Let's say you have a file `main_b.py` with your **FastAPI** app.
|
||||
Let's say that now the file `main.py` with your **FastAPI** app has some other **path operations**.
|
||||
|
||||
It has a `GET` operation that could return an error.
|
||||
|
||||
@@ -73,16 +73,24 @@ It has a `POST` operation that could return several errors.
|
||||
|
||||
Both *path operations* require an `X-Token` header.
|
||||
|
||||
```Python
|
||||
{!../../../docs_src/app_testing/main_b.py!}
|
||||
```
|
||||
=== "Python 3.6 and above"
|
||||
|
||||
```Python
|
||||
{!> ../../../docs_src/app_testing/app_b/main.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python
|
||||
{!> ../../../docs_src/app_testing/app_b_py310/main.py!}
|
||||
```
|
||||
|
||||
### Extended testing file
|
||||
|
||||
You could then have a `test_main_b.py`, the same as before, with the extended tests:
|
||||
You could then update `test_main.py` with the extended tests:
|
||||
|
||||
```Python
|
||||
{!../../../docs_src/app_testing/test_main_b.py!}
|
||||
{!> ../../../docs_src/app_testing/app_b/test_main.py!}
|
||||
```
|
||||
|
||||
Whenever you need the client to pass information in the request and you don't know how to, you can search (Google) how to do it in `requests`.
|
||||
|
||||
@@ -29,9 +29,6 @@ theme:
|
||||
repo_name: tiangolo/fastapi
|
||||
repo_url: https://github.com/tiangolo/fastapi
|
||||
edit_uri: ''
|
||||
google_analytics:
|
||||
- UA-133183413-1
|
||||
- auto
|
||||
plugins:
|
||||
- search
|
||||
- markdownextradata:
|
||||
@@ -43,11 +40,13 @@ nav:
|
||||
- az: /az/
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fa: /fa/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
- ru: /ru/
|
||||
@@ -143,6 +142,7 @@ nav:
|
||||
- advanced/extending-openapi.md
|
||||
- advanced/openapi-callbacks.md
|
||||
- advanced/wsgi.md
|
||||
- advanced/generate-clients.md
|
||||
- async.md
|
||||
- Deployment:
|
||||
- deployment/index.md
|
||||
@@ -176,8 +176,12 @@ markdown_extensions:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
extra:
|
||||
analytics:
|
||||
provider: google
|
||||
property: UA-133183413-1
|
||||
social:
|
||||
- icon: fontawesome/brands/github-alt
|
||||
link: https://github.com/tiangolo/fastapi
|
||||
@@ -202,6 +206,8 @@ extra:
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fa/
|
||||
name: fa
|
||||
- link: /fr/
|
||||
name: fr - français
|
||||
- link: /id/
|
||||
@@ -212,6 +218,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
name: pl
|
||||
- link: /pt/
|
||||
|
||||
@@ -22,16 +22,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="announce-right" style="position: relative;">
|
||||
<!-- <div class="item">
|
||||
<a title="The launchpad for all your (team's) ideas" style="display: block; position: relative;" href="https://www.deta.sh/?ref=fastapi" target="_blank">
|
||||
<span class="sponsor-badge">sponsor</span>
|
||||
<img class="sponsor-image" src="/img/sponsors/deta-banner.svg" />
|
||||
</a>
|
||||
</div> -->
|
||||
<div class="item">
|
||||
<a title="Get three courses at 10% off their current prices! Plus, we'll be donating 10% of all profits from sales of this bundle to the FastAPI team." style="display: block; position: relative;" href="https://testdriven.io/talkpython/" target="_blank">
|
||||
<span class="sponsor-badge">sponsor</span>
|
||||
<img class="sponsor-image" src="/img/sponsors/fastapi-course-bundle-banner.svg" />
|
||||
<img class="sponsor-image" src="/img/sponsors/fastapi-course-bundle-banner.png" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="item">
|
||||
@@ -46,6 +40,50 @@
|
||||
<img class="sponsor-image" src="/img/sponsors/cryptapi-banner.svg" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="item">
|
||||
<a title="Join the team building a new SaaS platform that will change the computing world" style="display: block; position: relative;" href="https://classiq.link/mzg" target="_blank">
|
||||
<span class="sponsor-badge">sponsor</span>
|
||||
<img class="sponsor-image" src="/img/sponsors/classiq-banner.png" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="item">
|
||||
<a title="Dropbase - seamlessly collect, clean, and centralize data." style="display: block; position: relative;" href="https://www.dropbase.io/careers" target="_blank">
|
||||
<span class="sponsor-badge">sponsor</span>
|
||||
<img class="sponsor-image" src="/img/sponsors/dropbase-banner.svg" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{%- block scripts %}
|
||||
{{ super() }}
|
||||
<!-- DocsQA integration start -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/qabot@0.4"></script>
|
||||
<script>
|
||||
// This prevents the global search from interfering with qa-bot's internal text input.
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
document.querySelectorAll('qa-bot').forEach((x) => {
|
||||
x.addEventListener('keydown', (event) => {
|
||||
event.stopPropagation();
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<qa-bot
|
||||
server="https://tiangolo-fastapi.docsqa.jina.ai"
|
||||
theme="infer"
|
||||
title="FastAPI Bot"
|
||||
description="FastAPI framework, high performance, easy to learn, fast to code, ready for production"
|
||||
style="font-size: 0.8rem"
|
||||
>
|
||||
<template>
|
||||
<dl>
|
||||
<dt>You can ask questions about FastAPI. Try:</dt>
|
||||
<dd>How do you deploy FastAPI?</dd>
|
||||
<dd>What are type hints?</dd>
|
||||
<dd>What is OpenAPI?</dd>
|
||||
</dl>
|
||||
</template>
|
||||
</qa-bot>
|
||||
<!-- DocsQA integration end -->
|
||||
{%- endblock %}
|
||||
|
||||
@@ -439,7 +439,6 @@ Usadas por Pydantic:
|
||||
Usados por Starlette:
|
||||
|
||||
* <a href="https://requests.readthedocs.io" target="_blank"><code>requests</code></a> - Requerido si quieres usar el `TestClient`.
|
||||
* <a href="https://github.com/Tinche/aiofiles" target="_blank"><code>aiofiles</code></a> - Requerido si quieres usar `FileResponse` o `StaticFiles`.
|
||||
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Requerido si quieres usar la configuración por defecto de templates.
|
||||
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - Requerido si quieres dar soporte a <abbr title="convertir el string que viene de un HTTP request a datos de Python">"parsing"</abbr> de formularios, con `request.form()`.
|
||||
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Requerido para dar soporte a `SessionMiddleware`.
|
||||
|
||||
@@ -29,9 +29,6 @@ theme:
|
||||
repo_name: tiangolo/fastapi
|
||||
repo_url: https://github.com/tiangolo/fastapi
|
||||
edit_uri: ''
|
||||
google_analytics:
|
||||
- UA-133183413-1
|
||||
- auto
|
||||
plugins:
|
||||
- search
|
||||
- markdownextradata:
|
||||
@@ -43,11 +40,13 @@ nav:
|
||||
- az: /az/
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fa: /fa/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
- ru: /ru/
|
||||
@@ -80,8 +79,12 @@ markdown_extensions:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
extra:
|
||||
analytics:
|
||||
provider: google
|
||||
property: UA-133183413-1
|
||||
social:
|
||||
- icon: fontawesome/brands/github-alt
|
||||
link: https://github.com/tiangolo/fastapi
|
||||
@@ -106,6 +109,8 @@ extra:
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fa/
|
||||
name: fa
|
||||
- link: /fr/
|
||||
name: fr - français
|
||||
- link: /id/
|
||||
@@ -116,6 +121,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
name: pl
|
||||
- link: /pt/
|
||||
|
||||
468
docs/fa/docs/index.md
Normal file
@@ -0,0 +1,468 @@
|
||||
|
||||
{!../../../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+event%3Apush+branch%3Amaster" target="_blank">
|
||||
<img src="https://github.com/tiangolo/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
|
||||
</a>
|
||||
<a href="https://codecov.io/gh/tiangolo/fastapi" target="_blank">
|
||||
<img src="https://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>
|
||||
<a href="https://pypi.org/project/fastapi" target="_blank">
|
||||
<img src="https://img.shields.io/pypi/pyversions/fastapi.svg?color=%2334D058" alt="Supported Python versions">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
**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.6+
|
||||
|
||||
FastAPI stands on the shoulders of giants:
|
||||
|
||||
* <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> for the web parts.
|
||||
* <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> for the data parts.
|
||||
|
||||
## Installation
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install fastapi
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
You will also need an ASGI server, for production such as <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> or <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>.
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "uvicorn[standard]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## Example
|
||||
|
||||
### Create it
|
||||
|
||||
* Create a file `main.py` with:
|
||||
|
||||
```Python
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/")
|
||||
def read_root():
|
||||
return {"Hello": "World"}
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: Optional[str] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
<details markdown="1">
|
||||
<summary>Or use <code>async def</code>...</summary>
|
||||
|
||||
If your code uses `async` / `await`, use `async def`:
|
||||
|
||||
```Python hl_lines="9 14"
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/")
|
||||
async def read_root():
|
||||
return {"Hello": "World"}
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
async def read_item(item_id: int, q: Optional[str] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
**Note**:
|
||||
|
||||
If you don't know, check the _"In a hurry?"_ section about <a href="https://fastapi.tiangolo.com/async/#in-a-hurry" target="_blank">`async` and `await` in the docs</a>.
|
||||
|
||||
</details>
|
||||
|
||||
### Run it
|
||||
|
||||
Run the server with:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --reload
|
||||
|
||||
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
INFO: Started reloader process [28720]
|
||||
INFO: Started server process [28722]
|
||||
INFO: Waiting for application startup.
|
||||
INFO: Application startup complete.
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
<details markdown="1">
|
||||
<summary>About the command <code>uvicorn main:app --reload</code>...</summary>
|
||||
|
||||
The command `uvicorn main:app` refers to:
|
||||
|
||||
* `main`: the file `main.py` (the Python "module").
|
||||
* `app`: the object created inside of `main.py` with the line `app = FastAPI()`.
|
||||
* `--reload`: make the server restart after code changes. Only do this for development.
|
||||
|
||||
</details>
|
||||
|
||||
### Check it
|
||||
|
||||
Open your browser at <a href="http://127.0.0.1:8000/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1:8000/items/5?q=somequery</a>.
|
||||
|
||||
You will see the JSON response as:
|
||||
|
||||
```JSON
|
||||
{"item_id": 5, "q": "somequery"}
|
||||
```
|
||||
|
||||
You already created an API that:
|
||||
|
||||
* Receives HTTP requests in the _paths_ `/` and `/items/{item_id}`.
|
||||
* Both _paths_ take `GET` <em>operations</em> (also known as HTTP _methods_).
|
||||
* The _path_ `/items/{item_id}` has a _path parameter_ `item_id` that should be an `int`.
|
||||
* The _path_ `/items/{item_id}` has an optional `str` _query parameter_ `q`.
|
||||
|
||||
### Interactive API docs
|
||||
|
||||
Now go to <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||
|
||||
You will see the automatic interactive API documentation (provided by <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
|
||||
|
||||

|
||||
|
||||
### 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>):
|
||||
|
||||

|
||||
|
||||
## 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:
|
||||
|
||||

|
||||
|
||||
* Click on the button "Try it out", it allows you to fill the parameters and directly interact with the API:
|
||||
|
||||

|
||||
|
||||
* 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:
|
||||
|
||||

|
||||
|
||||
### 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:
|
||||
|
||||

|
||||
|
||||
### 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:
|
||||
|
||||

|
||||
|
||||
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).
|
||||
* **GraphQL** integration with <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> and other libraries.
|
||||
* Many extra features (thanks to Starlette) as:
|
||||
* **WebSockets**
|
||||
* 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://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.
|
||||
135
docs/fa/mkdocs.yml
Normal file
@@ -0,0 +1,135 @@
|
||||
site_name: FastAPI
|
||||
site_description: FastAPI framework, high performance, easy to learn, fast to code, ready for production
|
||||
site_url: https://fastapi.tiangolo.com/fa/
|
||||
theme:
|
||||
name: material
|
||||
custom_dir: overrides
|
||||
palette:
|
||||
- scheme: default
|
||||
primary: teal
|
||||
accent: amber
|
||||
toggle:
|
||||
icon: material/lightbulb
|
||||
name: Switch to light mode
|
||||
- scheme: slate
|
||||
primary: teal
|
||||
accent: amber
|
||||
toggle:
|
||||
icon: material/lightbulb-outline
|
||||
name: Switch to dark mode
|
||||
features:
|
||||
- search.suggest
|
||||
- search.highlight
|
||||
- content.tabs.link
|
||||
icon:
|
||||
repo: fontawesome/brands/github-alt
|
||||
logo: https://fastapi.tiangolo.com/img/icon-white.svg
|
||||
favicon: https://fastapi.tiangolo.com/img/favicon.png
|
||||
language: fa
|
||||
repo_name: tiangolo/fastapi
|
||||
repo_url: https://github.com/tiangolo/fastapi
|
||||
edit_uri: ''
|
||||
plugins:
|
||||
- search
|
||||
- markdownextradata:
|
||||
data: data
|
||||
nav:
|
||||
- FastAPI: index.md
|
||||
- Languages:
|
||||
- en: /
|
||||
- az: /az/
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fa: /fa/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
- ru: /ru/
|
||||
- sq: /sq/
|
||||
- tr: /tr/
|
||||
- uk: /uk/
|
||||
- zh: /zh/
|
||||
markdown_extensions:
|
||||
- toc:
|
||||
permalink: true
|
||||
- markdown.extensions.codehilite:
|
||||
guess_lang: false
|
||||
- mdx_include:
|
||||
base_path: docs
|
||||
- admonition
|
||||
- codehilite
|
||||
- extra
|
||||
- pymdownx.superfences:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
extra:
|
||||
analytics:
|
||||
provider: google
|
||||
property: UA-133183413-1
|
||||
social:
|
||||
- icon: fontawesome/brands/github-alt
|
||||
link: https://github.com/tiangolo/fastapi
|
||||
- icon: fontawesome/brands/discord
|
||||
link: https://discord.gg/VQjSZaeJmf
|
||||
- icon: fontawesome/brands/twitter
|
||||
link: https://twitter.com/fastapi
|
||||
- icon: fontawesome/brands/linkedin
|
||||
link: https://www.linkedin.com/in/tiangolo
|
||||
- icon: fontawesome/brands/dev
|
||||
link: https://dev.to/tiangolo
|
||||
- icon: fontawesome/brands/medium
|
||||
link: https://medium.com/@tiangolo
|
||||
- icon: fontawesome/solid/globe
|
||||
link: https://tiangolo.com
|
||||
alternate:
|
||||
- link: /
|
||||
name: en - English
|
||||
- link: /az/
|
||||
name: az
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fa/
|
||||
name: fa
|
||||
- link: /fr/
|
||||
name: fr - français
|
||||
- link: /id/
|
||||
name: id
|
||||
- link: /it/
|
||||
name: it - italiano
|
||||
- link: /ja/
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
name: pl
|
||||
- link: /pt/
|
||||
name: pt - português
|
||||
- link: /ru/
|
||||
name: ru - русский язык
|
||||
- link: /sq/
|
||||
name: sq - shqip
|
||||
- link: /tr/
|
||||
name: tr - Türkçe
|
||||
- link: /uk/
|
||||
name: uk - українська мова
|
||||
- link: /zh/
|
||||
name: zh - 汉语
|
||||
extra_css:
|
||||
- https://fastapi.tiangolo.com/css/termynal.css
|
||||
- https://fastapi.tiangolo.com/css/custom.css
|
||||
extra_javascript:
|
||||
- https://fastapi.tiangolo.com/js/termynal.js
|
||||
- https://fastapi.tiangolo.com/js/custom.js
|
||||
0
docs/fa/overrides/.gitignore
vendored
Normal file
@@ -114,6 +114,8 @@ Ce sont les **Sponsors**. 😎
|
||||
|
||||
Ils soutiennent mon travail avec **FastAPI** (et d'autres) avec <a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub Sponsors</a>.
|
||||
|
||||
{% if sponsors %}
|
||||
|
||||
{% if sponsors.gold %}
|
||||
|
||||
### Gold Sponsors
|
||||
@@ -141,6 +143,7 @@ Ils soutiennent mon travail avec **FastAPI** (et d'autres) avec <a href="https:/
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
### Individual Sponsors
|
||||
|
||||
{% if github_sponsors %}
|
||||
|
||||
@@ -447,7 +447,6 @@ Used by Pydantic:
|
||||
Used by Starlette:
|
||||
|
||||
* <a href="https://requests.readthedocs.io" target="_blank"><code>requests</code></a> - Required if you want to use the `TestClient`.
|
||||
* <a href="https://github.com/Tinche/aiofiles" target="_blank"><code>aiofiles</code></a> - Required if you want to use `FileResponse` or `StaticFiles`.
|
||||
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
|
||||
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`.
|
||||
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Required for `SessionMiddleware` support.
|
||||
|
||||
@@ -111,7 +111,7 @@ Mais vous auriez le même support de l'éditeur avec <a href="https://www.jetbra
|
||||
<img src="/img/tutorial/body/image05.png">
|
||||
|
||||
!!! tip "Astuce"
|
||||
Si vous utilisez <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> comme éditeur, vous pouvez utiliser le Plugin <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a>.
|
||||
Si vous utilisez <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> comme éditeur, vous pouvez utiliser le Plugin <a href="https://github.com/koxudaxi/pydantic-pycharm-plugin/" class="external-link" target="_blank">Pydantic PyCharm Plugin</a>.
|
||||
|
||||
Ce qui améliore le support pour les modèles Pydantic avec :
|
||||
|
||||
|
||||
@@ -29,9 +29,6 @@ theme:
|
||||
repo_name: tiangolo/fastapi
|
||||
repo_url: https://github.com/tiangolo/fastapi
|
||||
edit_uri: ''
|
||||
google_analytics:
|
||||
- UA-133183413-1
|
||||
- auto
|
||||
plugins:
|
||||
- search
|
||||
- markdownextradata:
|
||||
@@ -43,11 +40,13 @@ nav:
|
||||
- az: /az/
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fa: /fa/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
- ru: /ru/
|
||||
@@ -85,8 +84,12 @@ markdown_extensions:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
extra:
|
||||
analytics:
|
||||
provider: google
|
||||
property: UA-133183413-1
|
||||
social:
|
||||
- icon: fontawesome/brands/github-alt
|
||||
link: https://github.com/tiangolo/fastapi
|
||||
@@ -111,6 +114,8 @@ extra:
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fa/
|
||||
name: fa
|
||||
- link: /fr/
|
||||
name: fr - français
|
||||
- link: /id/
|
||||
@@ -121,6 +126,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
name: pl
|
||||
- link: /pt/
|
||||
|
||||
@@ -447,7 +447,6 @@ Used by Pydantic:
|
||||
Used by Starlette:
|
||||
|
||||
* <a href="https://requests.readthedocs.io" target="_blank"><code>requests</code></a> - Required if you want to use the `TestClient`.
|
||||
* <a href="https://github.com/Tinche/aiofiles" target="_blank"><code>aiofiles</code></a> - Required if you want to use `FileResponse` or `StaticFiles`.
|
||||
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
|
||||
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`.
|
||||
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Required for `SessionMiddleware` support.
|
||||
|
||||
@@ -29,9 +29,6 @@ theme:
|
||||
repo_name: tiangolo/fastapi
|
||||
repo_url: https://github.com/tiangolo/fastapi
|
||||
edit_uri: ''
|
||||
google_analytics:
|
||||
- UA-133183413-1
|
||||
- auto
|
||||
plugins:
|
||||
- search
|
||||
- markdownextradata:
|
||||
@@ -43,11 +40,13 @@ nav:
|
||||
- az: /az/
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fa: /fa/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
- ru: /ru/
|
||||
@@ -70,8 +69,12 @@ markdown_extensions:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
extra:
|
||||
analytics:
|
||||
provider: google
|
||||
property: UA-133183413-1
|
||||
social:
|
||||
- icon: fontawesome/brands/github-alt
|
||||
link: https://github.com/tiangolo/fastapi
|
||||
@@ -96,6 +99,8 @@ extra:
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fa/
|
||||
name: fa
|
||||
- link: /fr/
|
||||
name: fr - français
|
||||
- link: /id/
|
||||
@@ -106,6 +111,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
name: pl
|
||||
- link: /pt/
|
||||
|
||||
@@ -444,7 +444,6 @@ Used by Pydantic:
|
||||
Used by Starlette:
|
||||
|
||||
* <a href="https://requests.readthedocs.io" target="_blank"><code>requests</code></a> - Required if you want to use the `TestClient`.
|
||||
* <a href="https://github.com/Tinche/aiofiles" target="_blank"><code>aiofiles</code></a> - Required if you want to use `FileResponse` or `StaticFiles`.
|
||||
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
|
||||
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`.
|
||||
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Required for `SessionMiddleware` support.
|
||||
|
||||
@@ -29,9 +29,6 @@ theme:
|
||||
repo_name: tiangolo/fastapi
|
||||
repo_url: https://github.com/tiangolo/fastapi
|
||||
edit_uri: ''
|
||||
google_analytics:
|
||||
- UA-133183413-1
|
||||
- auto
|
||||
plugins:
|
||||
- search
|
||||
- markdownextradata:
|
||||
@@ -43,11 +40,13 @@ nav:
|
||||
- az: /az/
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fa: /fa/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
- ru: /ru/
|
||||
@@ -70,8 +69,12 @@ markdown_extensions:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
extra:
|
||||
analytics:
|
||||
provider: google
|
||||
property: UA-133183413-1
|
||||
social:
|
||||
- icon: fontawesome/brands/github-alt
|
||||
link: https://github.com/tiangolo/fastapi
|
||||
@@ -96,6 +99,8 @@ extra:
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fa/
|
||||
name: fa
|
||||
- link: /fr/
|
||||
name: fr - français
|
||||
- link: /id/
|
||||
@@ -106,6 +111,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
name: pl
|
||||
- link: /pt/
|
||||
|
||||
58
docs/ja/docs/advanced/conditional-openapi.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# 条件付き OpenAPI
|
||||
|
||||
必要であれば、設定と環境変数を利用して、環境に応じて条件付きでOpenAPIを構成することが可能です。また、完全にOpenAPIを無効にすることもできます。
|
||||
|
||||
## セキュリティとAPI、およびドキュメントについて
|
||||
|
||||
本番環境においてドキュメントのUIを非表示にすることによって、APIを保護しようと *すべきではありません*。
|
||||
|
||||
それは、APIのセキュリティの強化にはならず、*path operations* は依然として利用可能です。
|
||||
|
||||
もしセキュリティ上の欠陥がソースコードにあるならば、それは存在したままです。
|
||||
|
||||
ドキュメンテーションを非表示にするのは、単にあなたのAPIへのアクセス方法を難解にするだけでなく、同時にあなた自身の本番環境でのAPIのデバッグを困難にしてしまう可能性があります。単純に、 <a href="https://en.wikipedia.org/wiki/Security_through_obscurity" class="external-link" target="_blank">Security through obscurity</a> の一つの形態として考えられるでしょう。
|
||||
|
||||
もしあなたのAPIのセキュリティを強化したいなら、いくつかのよりよい方法があります。例を示すと、
|
||||
|
||||
* リクエストボディとレスポンスのためのPydanticモデルの定義を見直す。
|
||||
* 依存関係に基づきすべての必要なパーミッションとロールを設定する。
|
||||
* パスワードを絶対に平文で保存しない。パスワードハッシュのみを保存する。
|
||||
* PasslibやJWTトークンに代表される、よく知られた暗号化ツールを使って実装する。
|
||||
* そして必要なところでは、もっと細かいパーミッション制御をOAuth2スコープを使って行う。
|
||||
* など
|
||||
|
||||
それでも、例えば本番環境のような特定の環境のみで、あるいは環境変数の設定によってAPIドキュメントをどうしても無効にしたいという、非常に特殊なユースケースがあるかもしれません。
|
||||
|
||||
## 設定と環境変数による条件付き OpenAPI
|
||||
|
||||
生成するOpenAPIとドキュメントUIの構成は、共通のPydanticの設定を使用して簡単に切り替えられます。
|
||||
|
||||
例えば、
|
||||
|
||||
```Python hl_lines="6 11"
|
||||
{!../../../docs_src/conditional_openapi/tutorial001.py!}
|
||||
```
|
||||
|
||||
ここでは `openapi_url` の設定を、デフォルトの `"/openapi.json"` のまま宣言しています。
|
||||
|
||||
そして、これを `FastAPI` appを作る際に使います。
|
||||
|
||||
それから、以下のように `OPENAPI_URL` という環境変数を空文字列に設定することによってOpenAPI (UIドキュメントを含む) を無効化することができます。
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ OPENAPI_URL= uvicorn main:app
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
すると、以下のように `/openapi.json`, `/docs`, `/redoc` のどのURLにアクセスしても、 `404 Not Found` エラーが返ってくるようになります。
|
||||
|
||||
```JSON
|
||||
{
|
||||
"detail": "Not Found"
|
||||
}
|
||||
```
|
||||
@@ -115,6 +115,8 @@ FastAPIには、様々なバックグラウンドの人々を歓迎する素晴
|
||||
|
||||
彼らは、<a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub Sponsors</a> を介して私の **FastAPI** などに関する活動を支援してくれています。
|
||||
|
||||
{% if sponsors %}
|
||||
|
||||
{% if sponsors.gold %}
|
||||
|
||||
### Gold Sponsors
|
||||
@@ -142,6 +144,8 @@ FastAPIには、様々なバックグラウンドの人々を歓迎する素晴
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
### Individual Sponsors
|
||||
|
||||
{% if github_sponsors %}
|
||||
|
||||
@@ -437,7 +437,6 @@ Pydantic によって使用されるもの:
|
||||
Starlette によって使用されるもの:
|
||||
|
||||
- <a href="https://requests.readthedocs.io" target="_blank"><code>requests</code></a> - `TestClient`を使用するために必要です。
|
||||
- <a href="https://github.com/Tinche/aiofiles" target="_blank"><code>aiofiles</code></a> - `FileResponse` または `StaticFiles`を使用したい場合は必要です。
|
||||
- <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - デフォルトのテンプレート設定を使用する場合は必要です。
|
||||
- <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>`request.form()`からの変換をサポートしたい場合は必要です。
|
||||
- <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - `SessionMiddleware` サポートのためには必要です。
|
||||
|
||||
@@ -162,4 +162,4 @@ APIはほとんどの場合 **レスポンス** ボディを送らなければ
|
||||
|
||||
## Pydanticを使わない方法
|
||||
|
||||
もしPydanticモデルを使用したくない場合は、**ボディ**パラメータが利用できます。[Body - Multiple Parameters: Singular values in body](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank}を確認してください。
|
||||
もしPydanticモデルを使用したくない場合は、**Body**パラメータが利用できます。[Body - Multiple Parameters: Singular values in body](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank}を確認してください。
|
||||
|
||||
@@ -2,20 +2,6 @@
|
||||
|
||||
`StaticFiles` を使用して、ディレクトリから静的ファイルを自動的に提供できます。
|
||||
|
||||
## `aiofiles` をインストール
|
||||
|
||||
まず、`aiofiles` をインストールする必要があります:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install aiofiles
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## `StaticFiles` の使用
|
||||
|
||||
* `StaticFiles` をインポート。
|
||||
|
||||
@@ -29,9 +29,6 @@ theme:
|
||||
repo_name: tiangolo/fastapi
|
||||
repo_url: https://github.com/tiangolo/fastapi
|
||||
edit_uri: ''
|
||||
google_analytics:
|
||||
- UA-133183413-1
|
||||
- auto
|
||||
plugins:
|
||||
- search
|
||||
- markdownextradata:
|
||||
@@ -43,11 +40,13 @@ nav:
|
||||
- az: /az/
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fa: /fa/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
- ru: /ru/
|
||||
@@ -81,6 +80,7 @@ nav:
|
||||
- advanced/additional-status-codes.md
|
||||
- advanced/response-directly.md
|
||||
- advanced/custom-response.md
|
||||
- advanced/conditional-openapi.md
|
||||
- async.md
|
||||
- デプロイ:
|
||||
- deployment/index.md
|
||||
@@ -110,8 +110,12 @@ markdown_extensions:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
extra:
|
||||
analytics:
|
||||
provider: google
|
||||
property: UA-133183413-1
|
||||
social:
|
||||
- icon: fontawesome/brands/github-alt
|
||||
link: https://github.com/tiangolo/fastapi
|
||||
@@ -136,6 +140,8 @@ extra:
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fa/
|
||||
name: fa
|
||||
- link: /fr/
|
||||
name: fr - français
|
||||
- link: /id/
|
||||
@@ -146,6 +152,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
name: pl
|
||||
- link: /pt/
|
||||
|
||||
@@ -35,7 +35,7 @@ FastAPI는 현대적이고, 빠르며(고성능), 파이썬 표준 타입 힌트
|
||||
* **직관적**: 훌륭한 편집기 지원. 모든 곳에서 <abbr title="also known as auto-complete, autocompletion, IntelliSense">자동완성</abbr>. 적은 디버깅 시간.
|
||||
* **쉬움**: 쉽게 사용하고 배우도록 설계. 적은 문서 읽기 시간.
|
||||
* **짧음**: 코드 중복 최소화. 각 매개변수 선언의 여러 기능. 적은 버그.
|
||||
* **견고함**: 준비된 프로덕션 용 코드를 얻으세요. 자동 대화형 문서와 함께.
|
||||
* **견고함**: 준비된 프로덕션 용 코드를 얻으십시오. 자동 대화형 문서와 함께.
|
||||
* **표준 기반**: API에 대한 (완전히 호환되는) 개방형 표준 기반: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (이전에 Swagger로 알려졌던) 및 <a href="http://json-schema.org/" class="external-link" target="_blank">JSON 스키마</a>.
|
||||
|
||||
<small>* 내부 개발팀의 프로덕션 애플리케이션을 빌드한 테스트에 근거한 측정</small>
|
||||
@@ -89,9 +89,9 @@ FastAPI는 현대적이고, 빠르며(고성능), 파이썬 표준 타입 힌트
|
||||
|
||||
---
|
||||
|
||||
"_REST API를 만들기 위해 **현대적인 프레임워크**를 찾고 있다면 **FastAPI**를 확인해 보세요. [...] 빠르고, 쓰기 쉽고, 배우기도 쉽습니다 [...]_"
|
||||
"_REST API를 만들기 위해 **현대적인 프레임워크**를 찾고 있다면 **FastAPI**를 확인해 보십시오. [...] 빠르고, 쓰기 쉽고, 배우기도 쉽습니다 [...]_"
|
||||
|
||||
"_우리 **API**를 **FastAPI**로 바꿨습니다 [...] 아마 여러분도 좋아하실 겁니다 [...]_"
|
||||
"_우리 **API**를 **FastAPI**로 바꿨습니다 [...] 아마 여러분도 좋아하실 것입니다 [...]_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> 설립자 - <a href="https://spacy.io" target="_blank">spaCy</a> 제작자</strong> <a href="https://twitter.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://twitter.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
@@ -193,7 +193,7 @@ async def read_item(item_id: int, q: Optional[str] = None):
|
||||
|
||||
### 실행하기
|
||||
|
||||
서버를 실행하세요:
|
||||
서버를 실행하십시오:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
@@ -239,7 +239,7 @@ INFO: Application startup complete.
|
||||
|
||||
### 대화형 API 문서
|
||||
|
||||
이제 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>로 가보세요.
|
||||
이제 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>로 가보십시오.
|
||||
|
||||
자동 대화형 API 문서를 볼 수 있습니다 (<a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a> 제공):
|
||||
|
||||
@@ -388,7 +388,7 @@ item: Item
|
||||
|
||||
우리는 그저 수박 겉핡기만 했을 뿐인데 여러분은 벌써 어떻게 작동하는지 알고 있습니다.
|
||||
|
||||
다음 줄을 바꿔보세요:
|
||||
다음 줄을 바꿔보십시오:
|
||||
|
||||
```Python
|
||||
return {"item_name": item.name, "item_id": item_id}
|
||||
@@ -443,11 +443,10 @@ Pydantic이 사용하는:
|
||||
Starlette이 사용하는:
|
||||
|
||||
* <a href="http://docs.python-requests.org" target="_blank"><code>requests</code></a> - `TestClient`를 사용하려면 필요.
|
||||
* <a href="https://github.com/Tinche/aiofiles" target="_blank"><code>aiofiles</code></a> - `FileResponse` 또는 `StaticFiles`를 사용하려면 필요.
|
||||
* <a href="http://jinja.pocoo.org" target="_blank"><code>jinja2</code></a> - 기본 템플릿 설정을 사용하려면 필요.
|
||||
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - `request.form()`과 함께 <abbr title="HTTP 요청에서 파이썬 데이터로 가는 문자열 변환">"parsing"</abbr>의 지원을 원하면 필요.
|
||||
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - `SessionMiddleware` 지원을 위해 필요.
|
||||
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Starlette의 `SchemaGenerator` 지원을 위해 필요 (FastAPI와 쓸때는 필요가 없을 겁니다).
|
||||
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Starlette의 `SchemaGenerator` 지원을 위해 필요 (FastAPI와 쓸때는 필요 없을 것입니다).
|
||||
* <a href="https://graphene-python.org/" target="_blank"><code>graphene</code></a> - `GraphQLApp` 지원을 위해 필요.
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - `UJSONResponse`를 사용하려면 필요.
|
||||
|
||||
|
||||
@@ -29,9 +29,6 @@ theme:
|
||||
repo_name: tiangolo/fastapi
|
||||
repo_url: https://github.com/tiangolo/fastapi
|
||||
edit_uri: ''
|
||||
google_analytics:
|
||||
- UA-133183413-1
|
||||
- auto
|
||||
plugins:
|
||||
- search
|
||||
- markdownextradata:
|
||||
@@ -43,11 +40,13 @@ nav:
|
||||
- az: /az/
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fa: /fa/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
- ru: /ru/
|
||||
@@ -80,8 +79,12 @@ markdown_extensions:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
extra:
|
||||
analytics:
|
||||
provider: google
|
||||
property: UA-133183413-1
|
||||
social:
|
||||
- icon: fontawesome/brands/github-alt
|
||||
link: https://github.com/tiangolo/fastapi
|
||||
@@ -106,6 +109,8 @@ extra:
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fa/
|
||||
name: fa
|
||||
- link: /fr/
|
||||
name: fr - français
|
||||
- link: /id/
|
||||
@@ -116,6 +121,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
name: pl
|
||||
- link: /pt/
|
||||
|
||||
468
docs/nl/docs/index.md
Normal file
@@ -0,0 +1,468 @@
|
||||
|
||||
{!../../../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+event%3Apush+branch%3Amaster" target="_blank">
|
||||
<img src="https://github.com/tiangolo/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
|
||||
</a>
|
||||
<a href="https://codecov.io/gh/tiangolo/fastapi" target="_blank">
|
||||
<img src="https://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>
|
||||
<a href="https://pypi.org/project/fastapi" target="_blank">
|
||||
<img src="https://img.shields.io/pypi/pyversions/fastapi.svg?color=%2334D058" alt="Supported Python versions">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
**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.6+
|
||||
|
||||
FastAPI stands on the shoulders of giants:
|
||||
|
||||
* <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> for the web parts.
|
||||
* <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> for the data parts.
|
||||
|
||||
## Installation
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install fastapi
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
You will also need an ASGI server, for production such as <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> or <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>.
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "uvicorn[standard]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## Example
|
||||
|
||||
### Create it
|
||||
|
||||
* Create a file `main.py` with:
|
||||
|
||||
```Python
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/")
|
||||
def read_root():
|
||||
return {"Hello": "World"}
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: Optional[str] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
<details markdown="1">
|
||||
<summary>Or use <code>async def</code>...</summary>
|
||||
|
||||
If your code uses `async` / `await`, use `async def`:
|
||||
|
||||
```Python hl_lines="9 14"
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/")
|
||||
async def read_root():
|
||||
return {"Hello": "World"}
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
async def read_item(item_id: int, q: Optional[str] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
**Note**:
|
||||
|
||||
If you don't know, check the _"In a hurry?"_ section about <a href="https://fastapi.tiangolo.com/async/#in-a-hurry" target="_blank">`async` and `await` in the docs</a>.
|
||||
|
||||
</details>
|
||||
|
||||
### Run it
|
||||
|
||||
Run the server with:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --reload
|
||||
|
||||
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
INFO: Started reloader process [28720]
|
||||
INFO: Started server process [28722]
|
||||
INFO: Waiting for application startup.
|
||||
INFO: Application startup complete.
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
<details markdown="1">
|
||||
<summary>About the command <code>uvicorn main:app --reload</code>...</summary>
|
||||
|
||||
The command `uvicorn main:app` refers to:
|
||||
|
||||
* `main`: the file `main.py` (the Python "module").
|
||||
* `app`: the object created inside of `main.py` with the line `app = FastAPI()`.
|
||||
* `--reload`: make the server restart after code changes. Only do this for development.
|
||||
|
||||
</details>
|
||||
|
||||
### Check it
|
||||
|
||||
Open your browser at <a href="http://127.0.0.1:8000/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1:8000/items/5?q=somequery</a>.
|
||||
|
||||
You will see the JSON response as:
|
||||
|
||||
```JSON
|
||||
{"item_id": 5, "q": "somequery"}
|
||||
```
|
||||
|
||||
You already created an API that:
|
||||
|
||||
* Receives HTTP requests in the _paths_ `/` and `/items/{item_id}`.
|
||||
* Both _paths_ take `GET` <em>operations</em> (also known as HTTP _methods_).
|
||||
* The _path_ `/items/{item_id}` has a _path parameter_ `item_id` that should be an `int`.
|
||||
* The _path_ `/items/{item_id}` has an optional `str` _query parameter_ `q`.
|
||||
|
||||
### Interactive API docs
|
||||
|
||||
Now go to <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||
|
||||
You will see the automatic interactive API documentation (provided by <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
|
||||
|
||||

|
||||
|
||||
### 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>):
|
||||
|
||||

|
||||
|
||||
## 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:
|
||||
|
||||

|
||||
|
||||
* Click on the button "Try it out", it allows you to fill the parameters and directly interact with the API:
|
||||
|
||||

|
||||
|
||||
* 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:
|
||||
|
||||

|
||||
|
||||
### 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:
|
||||
|
||||

|
||||
|
||||
### 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:
|
||||
|
||||

|
||||
|
||||
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).
|
||||
* **GraphQL** integration with <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> and other libraries.
|
||||
* Many extra features (thanks to Starlette) as:
|
||||
* **WebSockets**
|
||||
* 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://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.
|
||||
135
docs/nl/mkdocs.yml
Normal file
@@ -0,0 +1,135 @@
|
||||
site_name: FastAPI
|
||||
site_description: FastAPI framework, high performance, easy to learn, fast to code, ready for production
|
||||
site_url: https://fastapi.tiangolo.com/nl/
|
||||
theme:
|
||||
name: material
|
||||
custom_dir: overrides
|
||||
palette:
|
||||
- scheme: default
|
||||
primary: teal
|
||||
accent: amber
|
||||
toggle:
|
||||
icon: material/lightbulb
|
||||
name: Switch to light mode
|
||||
- scheme: slate
|
||||
primary: teal
|
||||
accent: amber
|
||||
toggle:
|
||||
icon: material/lightbulb-outline
|
||||
name: Switch to dark mode
|
||||
features:
|
||||
- search.suggest
|
||||
- search.highlight
|
||||
- content.tabs.link
|
||||
icon:
|
||||
repo: fontawesome/brands/github-alt
|
||||
logo: https://fastapi.tiangolo.com/img/icon-white.svg
|
||||
favicon: https://fastapi.tiangolo.com/img/favicon.png
|
||||
language: nl
|
||||
repo_name: tiangolo/fastapi
|
||||
repo_url: https://github.com/tiangolo/fastapi
|
||||
edit_uri: ''
|
||||
plugins:
|
||||
- search
|
||||
- markdownextradata:
|
||||
data: data
|
||||
nav:
|
||||
- FastAPI: index.md
|
||||
- Languages:
|
||||
- en: /
|
||||
- az: /az/
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fa: /fa/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
- ru: /ru/
|
||||
- sq: /sq/
|
||||
- tr: /tr/
|
||||
- uk: /uk/
|
||||
- zh: /zh/
|
||||
markdown_extensions:
|
||||
- toc:
|
||||
permalink: true
|
||||
- markdown.extensions.codehilite:
|
||||
guess_lang: false
|
||||
- mdx_include:
|
||||
base_path: docs
|
||||
- admonition
|
||||
- codehilite
|
||||
- extra
|
||||
- pymdownx.superfences:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
extra:
|
||||
analytics:
|
||||
provider: google
|
||||
property: UA-133183413-1
|
||||
social:
|
||||
- icon: fontawesome/brands/github-alt
|
||||
link: https://github.com/tiangolo/fastapi
|
||||
- icon: fontawesome/brands/discord
|
||||
link: https://discord.gg/VQjSZaeJmf
|
||||
- icon: fontawesome/brands/twitter
|
||||
link: https://twitter.com/fastapi
|
||||
- icon: fontawesome/brands/linkedin
|
||||
link: https://www.linkedin.com/in/tiangolo
|
||||
- icon: fontawesome/brands/dev
|
||||
link: https://dev.to/tiangolo
|
||||
- icon: fontawesome/brands/medium
|
||||
link: https://medium.com/@tiangolo
|
||||
- icon: fontawesome/solid/globe
|
||||
link: https://tiangolo.com
|
||||
alternate:
|
||||
- link: /
|
||||
name: en - English
|
||||
- link: /az/
|
||||
name: az
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fa/
|
||||
name: fa
|
||||
- link: /fr/
|
||||
name: fr - français
|
||||
- link: /id/
|
||||
name: id
|
||||
- link: /it/
|
||||
name: it - italiano
|
||||
- link: /ja/
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
name: pl
|
||||
- link: /pt/
|
||||
name: pt - português
|
||||
- link: /ru/
|
||||
name: ru - русский язык
|
||||
- link: /sq/
|
||||
name: sq - shqip
|
||||
- link: /tr/
|
||||
name: tr - Türkçe
|
||||
- link: /uk/
|
||||
name: uk - українська мова
|
||||
- link: /zh/
|
||||
name: zh - 汉语
|
||||
extra_css:
|
||||
- https://fastapi.tiangolo.com/css/termynal.css
|
||||
- https://fastapi.tiangolo.com/css/custom.css
|
||||
extra_javascript:
|
||||
- https://fastapi.tiangolo.com/js/termynal.js
|
||||
- https://fastapi.tiangolo.com/js/custom.js
|
||||
0
docs/nl/overrides/.gitignore
vendored
Normal file
@@ -1,12 +1,8 @@
|
||||
|
||||
{!../../../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>
|
||||
<em>FastAPI to szybki, prosty w nauce i gotowy do użycia w produkcji framework</em>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://github.com/tiangolo/fastapi/actions?query=workflow%3ATest" target="_blank">
|
||||
@@ -22,29 +18,28 @@
|
||||
|
||||
---
|
||||
|
||||
**Documentation**: <a href="https://fastapi.tiangolo.com" target="_blank">https://fastapi.tiangolo.com</a>
|
||||
**Dokumentacja**: <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>
|
||||
**Kod żródłowy**: <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.
|
||||
FastAPI to nowoczesny, wydajny framework webowy do budowania API z użyciem Pythona 3.6+ bazujący na standardowym typowaniu Pythona.
|
||||
|
||||
The key features are:
|
||||
Kluczowe cechy:
|
||||
|
||||
* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
|
||||
* **Wydajność**: FastAPI jest bardzo wydajny, na równi z **NodeJS** oraz **Go** (dzięki Starlette i Pydantic). [Jeden z najszybszych dostępnych frameworków Pythonowych](#wydajnosc).
|
||||
* **Szybkość kodowania**: Przyśpiesza szybkość pisania nowych funkcjonalności o około 200% do 300%. *
|
||||
* **Mniejsza ilość błędów**: Zmniejsza ilość ludzkich (dewelopera) błędy o około 40%. *
|
||||
* **Intuicyjność**: Wspaniałe wsparcie dla edytorów kodu. Dostępne wszędzie <abbr title="znane jako auto-complete, autocompletion, IntelliSense">automatyczne uzupełnianie</abbr> kodu. Krótszy czas debugowania.
|
||||
* **Łatwość**: Zaprojektowany by być prosty i łatwy do nauczenia. Mniej czasu spędzonego na czytanie dokumentacji.
|
||||
* **Kompaktowość**: Minimalizacja powtarzającego się kodu. Wiele funkcjonalności dla każdej deklaracji parametru. Mniej błędów.
|
||||
* **Solidność**: Kod gotowy dla środowiska produkcyjnego. Wraz z automatyczną interaktywną dokumentacją.
|
||||
* **Bazujący na standardach**: Oparty na (i w pełni kompatybilny z) otwartych standardach API: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (wcześniej znane jako Swagger) oraz <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
|
||||
|
||||
* **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>* oszacowania bazowane na testach wykonanych przez wewnętrzny zespół deweloperów, budujących aplikacie używane na środowisku produkcyjnym.</small>
|
||||
|
||||
<small>* estimation based on tests on an internal development team, building production applications.</small>
|
||||
|
||||
## Sponsors
|
||||
## Sponsorzy
|
||||
|
||||
<!-- sponsors -->
|
||||
|
||||
@@ -59,9 +54,9 @@ The key features are:
|
||||
|
||||
<!-- /sponsors -->
|
||||
|
||||
<a href="https://fastapi.tiangolo.com/fastapi-people/#sponsors" class="external-link" target="_blank">Other sponsors</a>
|
||||
<a href="https://fastapi.tiangolo.com/fastapi-people/#sponsors" class="external-link" target="_blank">Inni sponsorzy</a>
|
||||
|
||||
## Opinions
|
||||
## Opinie
|
||||
|
||||
"_[...] 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._"
|
||||
|
||||
@@ -101,24 +96,24 @@ The key features are:
|
||||
|
||||
---
|
||||
|
||||
## **Typer**, the FastAPI of CLIs
|
||||
## **Typer**, FastAPI aplikacji konsolowych
|
||||
|
||||
<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>.
|
||||
Jeżeli tworzysz aplikacje <abbr title="aplikacja z interfejsem konsolowym">CLI</abbr>, która ma być używana w terminalu zamiast API, sprawdź <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**. ⌨️ 🚀
|
||||
**Typer** to młodsze rodzeństwo FastAPI. Jego celem jest pozostanie **FastAPI aplikacji konsolowych** . ⌨️ 🚀
|
||||
|
||||
## Requirements
|
||||
## Wymagania
|
||||
|
||||
Python 3.6+
|
||||
|
||||
FastAPI stands on the shoulders of giants:
|
||||
FastAPI oparty jest na:
|
||||
|
||||
* <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.
|
||||
* <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> dla części webowej.
|
||||
* <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> dla części obsługujących dane.
|
||||
|
||||
## Installation
|
||||
## Instalacja
|
||||
|
||||
<div class="termy">
|
||||
|
||||
@@ -130,7 +125,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>.
|
||||
Na serwerze produkcyjnym będziesz także potrzebował serwera ASGI, np. <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> lub <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>.
|
||||
|
||||
<div class="termy">
|
||||
|
||||
@@ -142,11 +137,11 @@ $ pip install uvicorn[standard]
|
||||
|
||||
</div>
|
||||
|
||||
## Example
|
||||
## Przykład
|
||||
|
||||
### Create it
|
||||
### Stwórz
|
||||
|
||||
* Create a file `main.py` with:
|
||||
* Utwórz plik o nazwie `main.py` z:
|
||||
|
||||
```Python
|
||||
from typing import Optional
|
||||
@@ -167,9 +162,9 @@ def read_item(item_id: int, q: Optional[str] = None):
|
||||
```
|
||||
|
||||
<details markdown="1">
|
||||
<summary>Or use <code>async def</code>...</summary>
|
||||
<summary>Albo użyj <code>async def</code>...</summary>
|
||||
|
||||
If your code uses `async` / `await`, use `async def`:
|
||||
Jeżeli twój kod korzysta z `async` / `await`, użyj `async def`:
|
||||
|
||||
```Python hl_lines="9 14"
|
||||
from typing import Optional
|
||||
@@ -189,15 +184,15 @@ async def read_item(item_id: int, q: Optional[str] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
**Note**:
|
||||
**Przypis**:
|
||||
|
||||
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>.
|
||||
Jeżeli nie znasz, sprawdź sekcję _"In a hurry?"_ o <a href="https://fastapi.tiangolo.com/async/#in-a-hurry" target="_blank">`async` i `await` w dokumentacji</a>.
|
||||
|
||||
</details>
|
||||
|
||||
### Run it
|
||||
### Uruchom
|
||||
|
||||
Run the server with:
|
||||
Uruchom serwer używając:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
@@ -214,54 +209,53 @@ INFO: Application startup complete.
|
||||
</div>
|
||||
|
||||
<details markdown="1">
|
||||
<summary>About the command <code>uvicorn main:app --reload</code>...</summary>
|
||||
<summary>O komendzie <code>uvicorn main:app --reload</code>...</summary>
|
||||
Komenda `uvicorn main:app` odnosi się do:
|
||||
|
||||
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.
|
||||
* `main`: plik `main.py` ("moduł" w Pythonie).
|
||||
* `app`: obiekt stworzony w `main.py` w lini `app = FastAPI()`.
|
||||
* `--reload`: spraw by serwer resetował się po każdej zmianie w kodzie. Używaj tego tylko w środowisku deweloperskim.
|
||||
|
||||
</details>
|
||||
|
||||
### Check it
|
||||
### Wypróbuj
|
||||
|
||||
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>.
|
||||
Otwórz link <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> w przeglądarce.
|
||||
|
||||
You will see the JSON response as:
|
||||
Zobaczysz następującą odpowiedź JSON:
|
||||
|
||||
```JSON
|
||||
{"item_id": 5, "q": "somequery"}
|
||||
```
|
||||
|
||||
You already created an API that:
|
||||
Właśnie stworzyłeś API które:
|
||||
|
||||
* 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`.
|
||||
* Otrzymuje żądania HTTP w _ścieżce_ `/` i `/items/{item_id}`.
|
||||
* Obie _ścieżki_ używają <em>operacji</em> `GET` (znane także jako _metody_ HTTP).
|
||||
* _Ścieżka_ `/items/{item_id}` ma _parametr ścieżki_ `item_id` który powinien być obiektem typu `int`.
|
||||
* _Ścieżka_ `/items/{item_id}` ma opcjonalny _parametr zapytania_ typu `str` o nazwie `q`.
|
||||
|
||||
### Interactive API docs
|
||||
### Interaktywna dokumentacja API
|
||||
|
||||
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>.
|
||||
Otwórz teraz stronę <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>):
|
||||
Zobaczysz automatyczną interaktywną dokumentację API (dostarczoną z pomocą <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
|
||||
|
||||

|
||||
|
||||
### Alternative API docs
|
||||
### Alternatywna dokumentacja API
|
||||
|
||||
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>.
|
||||
Otwórz teraz <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>):
|
||||
Zobaczysz alternatywną, lecz wciąż automatyczną dokumentację (wygenerowaną z pomocą <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>):
|
||||
|
||||

|
||||
|
||||
## Example upgrade
|
||||
## Aktualizacja przykładu
|
||||
|
||||
Now modify the file `main.py` to receive a body from a `PUT` request.
|
||||
Zmodyfikuj teraz plik `main.py`, aby otrzmywał treść (body) żądania `PUT`.
|
||||
|
||||
Declare the body using standard Python types, thanks to Pydantic.
|
||||
Zadeklaruj treść żądania, używając standardowych typów w Pythonie dzięki Pydantic.
|
||||
|
||||
```Python hl_lines="4 9-12 25-27"
|
||||
from typing import Optional
|
||||
@@ -293,175 +287,175 @@ 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).
|
||||
Serwer powinien przeładować się automatycznie (ponieważ dodałeś `--reload` do komendy `uvicorn` powyżej).
|
||||
|
||||
### Interactive API docs upgrade
|
||||
### Zaktualizowana interaktywna dokumentacja API
|
||||
|
||||
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>.
|
||||
Wejdź teraz na <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:
|
||||
* Interaktywna dokumentacja API zaktualizuje sie automatycznie, także z nową treścią żądania (body):
|
||||
|
||||

|
||||
|
||||
* Click on the button "Try it out", it allows you to fill the parameters and directly interact with the API:
|
||||
* Kliknij przycisk "Try it out" (wypróbuj), pozwoli Ci to wypełnić parametry i bezpośrednio użyć API:
|
||||
|
||||

|
||||
|
||||
* 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:
|
||||
* Kliknij potem przycisk "Execute" (wykonaj), interfejs użytkownika połączy się z API, wyśle parametry, otrzyma odpowiedź i wyświetli ją na ekranie:
|
||||
|
||||

|
||||
|
||||
### Alternative API docs upgrade
|
||||
### Zaktualizowana alternatywna dokumentacja API
|
||||
|
||||
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>.
|
||||
Otwórz teraz <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:
|
||||
* Alternatywna dokumentacja również pokaże zaktualizowane parametry i treść żądania (body):
|
||||
|
||||

|
||||
|
||||
### Recap
|
||||
### Podsumowanie
|
||||
|
||||
In summary, you declare **once** the types of parameters, body, etc. as function parameters.
|
||||
Podsumowując, musiałeś zadeklarować typy parametrów, treści żądania (body) itp. tylko **raz**, i są one dostępne jako parametry funkcji.
|
||||
|
||||
You do that with standard modern Python types.
|
||||
Robisz to tak samo jak ze standardowymi typami w Pythonie.
|
||||
|
||||
You don't have to learn a new syntax, the methods or classes of a specific library, etc.
|
||||
Nie musisz sie uczyć żadnej nowej składni, metod lub klas ze specyficznych bibliotek itp.
|
||||
|
||||
Just standard **Python 3.6+**.
|
||||
Po prostu standardowy **Python 3.6+**.
|
||||
|
||||
For example, for an `int`:
|
||||
Na przykład, dla danych typu `int`:
|
||||
|
||||
```Python
|
||||
item_id: int
|
||||
```
|
||||
|
||||
or for a more complex `Item` model:
|
||||
albo dla bardziej złożonego obiektu `Item`:
|
||||
|
||||
```Python
|
||||
item: Item
|
||||
```
|
||||
|
||||
...and with that single declaration you get:
|
||||
...i z pojedyńczą deklaracją otrzymujesz:
|
||||
|
||||
* 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:
|
||||
* Wsparcie edytorów kodu, wliczając:
|
||||
* Auto-uzupełnianie.
|
||||
* Sprawdzanie typów.
|
||||
* Walidacja danych:
|
||||
* Automatyczne i przejrzyste błędy gdy dane są niepoprawne.
|
||||
* Walidacja nawet dla głęboko zagnieżdżonych obiektów JSON.
|
||||
* <abbr title="znane również jako: serializacja, przetwarzanie, marshalling">Konwersja</abbr> danych wejściowych: przychodzących z sieci na Pythonowe typy. Pozwala na przetwarzanie danych:
|
||||
* 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:
|
||||
* Parametrów ścieżki.
|
||||
* Parametrów zapytania.
|
||||
* Dane cookies.
|
||||
* Dane nagłówków (headers).
|
||||
* Formularze.
|
||||
* Pliki.
|
||||
* <abbr title="znane również jako: serializacja, przetwarzanie, marshalling">Konwersja</abbr> danych wyjściowych: wychodzących z Pythona do sieci (jako JSON):
|
||||
* Przetwarzanie Pythonowych typów (`str`, `int`, `float`, `bool`, `list`, itp).
|
||||
* Obiekty `datetime`.
|
||||
* Obiekty `UUID`.
|
||||
* Modele baz danych.
|
||||
* ...i wiele więcej.
|
||||
* Automatyczne interaktywne dokumentacje API, wliczając 2 alternatywne interfejsy użytkownika:
|
||||
* Swagger UI.
|
||||
* ReDoc.
|
||||
|
||||
---
|
||||
|
||||
Coming back to the previous code example, **FastAPI** will:
|
||||
Wracając do poprzedniego przykładu, **FastAPI** :
|
||||
|
||||
* 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.
|
||||
* Potwierdzi, że w ścieżce jest `item_id` dla żądań `GET` i `PUT`.
|
||||
* Potwierdzi, że `item_id` jest typu `int` dla żądań `GET` i `PUT`.
|
||||
* Jeżeli nie jest, odbiorca zobaczy przydatną, przejrzystą wiadomość z błędem.
|
||||
* Sprawdzi czy w ścieżce jest opcjonalny parametr zapytania `q` (np. `http://127.0.0.1:8000/items/foo?q=somequery`) dla żądania `GET`.
|
||||
* Jako że parametr `q` jest zadeklarowany jako `= None`, jest on opcjonalny.
|
||||
* Gdyby tego `None` nie było, parametr ten byłby wymagany (tak jak treść żądania w żądaniu `PUT`).
|
||||
* Dla żądania `PUT` z ścieżką `/items/{item_id}`, odczyta treść żądania jako JSON:
|
||||
* Sprawdzi czy posiada wymagany atrybut `name`, który powinien być typu `str`.
|
||||
* Sprawdzi czy posiada wymagany atrybut `price`, który musi być typu `float`.
|
||||
* Sprawdzi czy posiada opcjonalny atrybut `is_offer`, który (jeżeli obecny) powinien być typu `bool`.
|
||||
* To wszystko będzie również działać dla głęboko zagnieżdżonych obiektów JSON.
|
||||
* Automatycznie konwertuje z i do JSON.
|
||||
* Dokumentuje wszystko w OpenAPI, które może być używane przez:
|
||||
* Interaktywne systemy dokumentacji.
|
||||
* Systemy automatycznego generowania kodu klienckiego, dla wielu języków.
|
||||
* Dostarczy bezpośrednio 2 interaktywne dokumentacje webowe.
|
||||
|
||||
---
|
||||
|
||||
We just scratched the surface, but you already get the idea of how it all works.
|
||||
To dopiero początek, ale już masz mniej-więcej pojęcie jak to wszystko działa.
|
||||
|
||||
Try changing the line with:
|
||||
Spróbuj zmienić linijkę:
|
||||
|
||||
```Python
|
||||
return {"item_name": item.name, "item_id": item_id}
|
||||
```
|
||||
|
||||
...from:
|
||||
...z:
|
||||
|
||||
```Python
|
||||
... "item_name": item.name ...
|
||||
```
|
||||
|
||||
...to:
|
||||
...na:
|
||||
|
||||
```Python
|
||||
... "item_price": item.price ...
|
||||
```
|
||||
|
||||
...and see how your editor will auto-complete the attributes and know their types:
|
||||
...i zobacz jak edytor kodu automatycznie uzupełni atrybuty i będzie znał ich typy:
|
||||
|
||||

|
||||
|
||||
For a more complete example including more features, see the <a href="https://fastapi.tiangolo.com/tutorial/">Tutorial - User Guide</a>.
|
||||
Dla bardziej kompletnych przykładów posiadających więcej funkcjonalności, zobacz <a href="https://fastapi.tiangolo.com/tutorial/">Tutorial - User Guide</a>.
|
||||
|
||||
**Spoiler alert**: the tutorial - user guide includes:
|
||||
**Uwaga Spoiler**: tutorial - user guide zawiera:
|
||||
|
||||
* 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**
|
||||
* Deklaracje **parametrów** z innych miejsc takich jak: **nagłówki**, **pliki cookies**, **formularze** i **pliki**.
|
||||
* Jak ustawić **ograniczenia walidacyjne** takie jak `maksymalna długość` lub `regex`.
|
||||
* Potężny i łatwy w użyciu system **<abbr title="znane jako komponenty, resources, providers, services, injectables">Dependency Injection</abbr>**.
|
||||
* Zabezpieczenia i autentykacja, wliczając wsparcie dla **OAuth2** z **tokenami JWT** oraz autoryzacją **HTTP Basic**.
|
||||
* Bardziej zaawansowane (ale równie proste) techniki deklarowania **głęboko zagnieżdżonych modeli JSON** (dzięki Pydantic).
|
||||
* Wiele dodatkowych funkcji (dzięki Starlette) takie jak:
|
||||
* **WebSockety**
|
||||
* **GraphQL**
|
||||
* extremely easy tests based on `requests` and `pytest`
|
||||
* bardzo proste testy bazujące na `requests` oraz `pytest`
|
||||
* **CORS**
|
||||
* **Cookie Sessions**
|
||||
* ...and more.
|
||||
* **Sesje cookie**
|
||||
* ...i więcej.
|
||||
|
||||
## Performance
|
||||
## Wydajność
|
||||
|
||||
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). (*)
|
||||
Niezależne benchmarki TechEmpower pokazują, że **FastAPI** (uruchomiony na serwerze Uvicorn) <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">jest jednym z najszybszych dostępnych Pythonowych frameworków</a>, zaraz po Starlette i Uvicorn (używanymi wewnątrznie przez FastAPI). (*)
|
||||
|
||||
To understand more about it, see the section <a href="https://fastapi.tiangolo.com/benchmarks/" class="internal-link" target="_blank">Benchmarks</a>.
|
||||
Aby dowiedzieć się o tym więcej, zobacz sekcję <a href="https://fastapi.tiangolo.com/benchmarks/" class="internal-link" target="_blank">Benchmarks</a>.
|
||||
|
||||
## Optional Dependencies
|
||||
## Opcjonalne zależności
|
||||
|
||||
Used by Pydantic:
|
||||
Używane przez 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.
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - dla szybszego <abbr title="przetwarzania stringa który przychodzi z żądaniem HTTP na dane używane przez Pythona">"parsowania"</abbr> danych JSON.
|
||||
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - dla walidacji adresów email.
|
||||
|
||||
Used by Starlette:
|
||||
Używane przez Starlette:
|
||||
|
||||
* <a href="https://requests.readthedocs.io" target="_blank"><code>requests</code></a> - Required if you want to use the `TestClient`.
|
||||
* <a href="https://github.com/Tinche/aiofiles" target="_blank"><code>aiofiles</code></a> - Required if you want to use `FileResponse` or `StaticFiles`.
|
||||
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
|
||||
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`.
|
||||
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Required for `SessionMiddleware` support.
|
||||
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Required for Starlette's `SchemaGenerator` support (you probably don't need it with FastAPI).
|
||||
* <a href="https://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`.
|
||||
* <a href="https://requests.readthedocs.io" target="_blank"><code>requests</code></a> - Wymagane jeżeli chcesz korzystać z `TestClient`.
|
||||
* <a href="https://github.com/Tinche/aiofiles" target="_blank"><code>aiofiles</code></a> - Wymagane jeżeli chcesz korzystać z `FileResponse` albo `StaticFiles`.
|
||||
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Wymagane jeżeli chcesz używać domyślnej konfiguracji szablonów.
|
||||
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - Wymagane jeżelich chcesz wsparcie <abbr title="przetwarzania stringa którzy przychodzi z żądaniem HTTP na dane używane przez Pythona">"parsowania"</abbr> formularzy, używając `request.form()`.
|
||||
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Wymagany dla wsparcia `SessionMiddleware`.
|
||||
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Wymagane dla wsparcia `SchemaGenerator` z Starlette (z FastAPI prawdopodobnie tego nie potrzebujesz).
|
||||
* <a href="https://graphene-python.org/" target="_blank"><code>graphene</code></a> - Wymagane dla wsparcia `GraphQLApp`.
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Wymagane jeżeli chcesz korzystać z `UJSONResponse`.
|
||||
|
||||
Used by FastAPI / Starlette:
|
||||
Używane przez 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`.
|
||||
* <a href="https://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - jako serwer, który ładuje i obsługuje Twoją aplikację.
|
||||
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - Wymagane jeżeli chcesz używać `ORJSONResponse`.
|
||||
|
||||
You can install all of these with `pip install fastapi[all]`.
|
||||
Możesz zainstalować wszystkie te aplikacje przy pomocy `pip install fastapi[all]`.
|
||||
|
||||
## License
|
||||
## Licencja
|
||||
|
||||
This project is licensed under the terms of the MIT license.
|
||||
Ten projekt jest na licencji MIT.
|
||||
|
||||
@@ -29,9 +29,6 @@ theme:
|
||||
repo_name: tiangolo/fastapi
|
||||
repo_url: https://github.com/tiangolo/fastapi
|
||||
edit_uri: ''
|
||||
google_analytics:
|
||||
- UA-133183413-1
|
||||
- auto
|
||||
plugins:
|
||||
- search
|
||||
- markdownextradata:
|
||||
@@ -43,11 +40,13 @@ nav:
|
||||
- az: /az/
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fa: /fa/
|
||||
- fr: /fr/
|
||||
- id: /id/
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
- ru: /ru/
|
||||
@@ -70,8 +69,12 @@ markdown_extensions:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
extra:
|
||||
analytics:
|
||||
provider: google
|
||||
property: UA-133183413-1
|
||||
social:
|
||||
- icon: fontawesome/brands/github-alt
|
||||
link: https://github.com/tiangolo/fastapi
|
||||
@@ -96,6 +99,8 @@ extra:
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fa/
|
||||
name: fa
|
||||
- link: /fr/
|
||||
name: fr - français
|
||||
- link: /id/
|
||||
@@ -106,6 +111,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
name: pl
|
||||
- link: /pt/
|
||||
|
||||
258
docs/pt/docs/deployment/deta.md
Normal file
@@ -0,0 +1,258 @@
|
||||
# Implantação FastAPI na Deta
|
||||
|
||||
Nessa seção você aprenderá sobre como realizar a implantação de uma aplicação **FastAPI** na <a href="https://www.deta.sh/?ref=fastapi" class="external-link" target="_blank">Deta</a> utilizando o plano gratuito. 🎁
|
||||
|
||||
Isso tudo levará aproximadamente **10 minutos**.
|
||||
|
||||
!!! info "Informação"
|
||||
<a href="https://www.deta.sh/?ref=fastapi" class="external-link" target="_blank">Deta</a> é uma patrocinadora do **FastAPI**. 🎉
|
||||
|
||||
## Uma aplicação **FastAPI** simples
|
||||
|
||||
* Crie e entre em um diretório para a sua aplicação, por exemplo, `./fastapideta/`.
|
||||
|
||||
### Código FastAPI
|
||||
|
||||
* Crie o arquivo `main.py` com:
|
||||
|
||||
```Python
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/")
|
||||
def read_root():
|
||||
return {"Hello": "World"}
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int):
|
||||
return {"item_id": item_id}
|
||||
```
|
||||
|
||||
### Requisitos
|
||||
|
||||
Agora, no mesmo diretório crie o arquivo `requirements.txt` com:
|
||||
|
||||
```text
|
||||
fastapi
|
||||
```
|
||||
|
||||
!!! tip "Dica"
|
||||
Você não precisa instalar Uvicorn para realizar a implantação na Deta, embora provavelmente queira instalá-lo para testar seu aplicativo localmente.
|
||||
|
||||
### Estrutura de diretório
|
||||
|
||||
Agora você terá o diretório `./fastapideta/` com dois arquivos:
|
||||
|
||||
```
|
||||
.
|
||||
└── main.py
|
||||
└── requirements.txt
|
||||
```
|
||||
|
||||
## Crie uma conta gratuita na Deta
|
||||
|
||||
Agora crie <a href="https://www.deta.sh/?ref=fastapi" class="external-link" target="_blank">uma conta gratuita na Deta</a>, você precisará apenas de um email e senha.
|
||||
|
||||
Você nem precisa de um cartão de crédito.
|
||||
|
||||
## Instale a CLI
|
||||
|
||||
Depois de ter sua conta criada, instale Deta <abbr title="Interface de Linha de Comando">CLI</abbr>:
|
||||
|
||||
=== "Linux, macOS"
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ curl -fsSL https://get.deta.dev/cli.sh | sh
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
=== "Windows PowerShell"
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ iwr https://get.deta.dev/cli.ps1 -useb | iex
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Após a instalação, abra um novo terminal para que a CLI seja detectada.
|
||||
|
||||
Em um novo terminal, confirme se foi instalado corretamente com:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ deta --help
|
||||
|
||||
Deta command line interface for managing deta micros.
|
||||
Complete documentation available at https://docs.deta.sh
|
||||
|
||||
Usage:
|
||||
deta [flags]
|
||||
deta [command]
|
||||
|
||||
Available Commands:
|
||||
auth Change auth settings for a deta micro
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
!!! tip "Dica"
|
||||
Se você tiver problemas ao instalar a CLI, verifique a <a href="https://docs.deta.sh/docs/micros/getting_started?ref=fastapi" class="external-link" target="_blank">documentação oficial da Deta</a>.
|
||||
|
||||
## Login pela CLI
|
||||
|
||||
Agora faça login na Deta pela CLI com:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ deta login
|
||||
|
||||
Please, log in from the web page. Waiting..
|
||||
Logged in successfully.
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Isso abrirá um navegador da Web e autenticará automaticamente.
|
||||
|
||||
## Implantação com Deta
|
||||
|
||||
Em seguida, implante seu aplicativo com a Deta CLI:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ deta new
|
||||
|
||||
Successfully created a new micro
|
||||
|
||||
// Notice the "endpoint" 🔍
|
||||
|
||||
{
|
||||
"name": "fastapideta",
|
||||
"runtime": "python3.7",
|
||||
"endpoint": "https://qltnci.deta.dev",
|
||||
"visor": "enabled",
|
||||
"http_auth": "enabled"
|
||||
}
|
||||
|
||||
Adding dependencies...
|
||||
|
||||
|
||||
---> 100%
|
||||
|
||||
|
||||
Successfully installed fastapi-0.61.1 pydantic-1.7.2 starlette-0.13.6
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Você verá uma mensagem JSON semelhante a:
|
||||
|
||||
```JSON hl_lines="4"
|
||||
{
|
||||
"name": "fastapideta",
|
||||
"runtime": "python3.7",
|
||||
"endpoint": "https://qltnci.deta.dev",
|
||||
"visor": "enabled",
|
||||
"http_auth": "enabled"
|
||||
}
|
||||
```
|
||||
|
||||
!!! tip "Dica"
|
||||
Sua implantação terá um URL `"endpoint"` diferente.
|
||||
|
||||
## Confira
|
||||
|
||||
Agora, abra seu navegador na URL do `endpoint`. No exemplo acima foi `https://qltnci.deta.dev`, mas o seu será diferente.
|
||||
|
||||
Você verá a resposta JSON do seu aplicativo FastAPI:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"Hello": "World"
|
||||
}
|
||||
```
|
||||
|
||||
Agora vá para o `/docs` da sua API, no exemplo acima seria `https://qltnci.deta.dev/docs`.
|
||||
|
||||
Ele mostrará sua documentação como:
|
||||
|
||||
<img src="/img/deployment/deta/image01.png">
|
||||
|
||||
## Permitir acesso público
|
||||
|
||||
Por padrão, a Deta lidará com a autenticação usando cookies para sua conta.
|
||||
|
||||
Mas quando estiver pronto, você pode torná-lo público com:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ deta auth disable
|
||||
|
||||
Successfully disabled http auth
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Agora você pode compartilhar essa URL com qualquer pessoa e elas conseguirão acessar sua API. 🚀
|
||||
|
||||
## HTTPS
|
||||
|
||||
Parabéns! Você realizou a implantação do seu app FastAPI na Deta! 🎉 🍰
|
||||
|
||||
Além disso, observe que a Deta lida corretamente com HTTPS para você, para que você não precise cuidar disso e tenha a certeza de que seus clientes terão uma conexão criptografada segura. ✅ 🔒
|
||||
|
||||
## Verifique o Visor
|
||||
|
||||
Na UI da sua documentação (você estará em um URL como `https://qltnci.deta.dev/docs`) envie um request para *operação de rota* `/items/{item_id}`.
|
||||
|
||||
Por exemplo com ID `5`.
|
||||
|
||||
Agora vá para <a href="https://web.deta.sh/" class="external-link" target="_blank">https://web.deta.sh</a>.
|
||||
|
||||
Você verá que há uma seção à esquerda chamada <abbr title="it comes from Micro(server)">"Micros"</abbr> com cada um dos seus apps.
|
||||
|
||||
Você verá uma aba com "Detalhes", e também a aba "Visor", vá para "Visor".
|
||||
|
||||
Lá você pode inspecionar as solicitações recentes enviadas ao seu aplicativo.
|
||||
|
||||
Você também pode editá-los e reproduzi-los novamente.
|
||||
|
||||
<img src="/img/deployment/deta/image02.png">
|
||||
|
||||
## Saiba mais
|
||||
|
||||
Em algum momento, você provavelmente desejará armazenar alguns dados para seu aplicativo de uma forma que persista ao longo do tempo. Para isso você pode usar <a href="https://docs.deta.sh/docs/base/py_tutorial?ref=fastapi" class="external-link" target="_blank">Deta Base</a>, que também tem um generoso **nível gratuito**.
|
||||
|
||||
Você também pode ler mais na <a href="https://docs.deta.sh?ref=fastapi" class="external-link" target="_blank">documentação da Deta</a>.
|
||||
|
||||
## Conceitos de implantação
|
||||
|
||||
Voltando aos conceitos que discutimos em [Deployments Concepts](./concepts.md){.internal-link target=_blank}, veja como cada um deles seria tratado com a Deta:
|
||||
|
||||
* **HTTPS**: Realizado pela Deta, eles fornecerão um subdomínio e lidarão com HTTPS automaticamente.
|
||||
* **Executando na inicialização**: Realizado pela Deta, como parte de seu serviço.
|
||||
* **Reinicialização**: Realizado pela Deta, como parte de seu serviço.
|
||||
* **Replicação**: Realizado pela Deta, como parte de seu serviço.
|
||||
* **Memória**: Limite predefinido pela Deta, você pode contatá-los para aumentá-lo.
|
||||
* **Etapas anteriores a inicialização**: Não suportado diretamente, você pode fazê-lo funcionar com o sistema Cron ou scripts adicionais.
|
||||
|
||||
!!! note "Nota"
|
||||
O Deta foi projetado para facilitar (e gratuitamente) a implantação rápida de aplicativos simples.
|
||||
|
||||
Ele pode simplificar vários casos de uso, mas, ao mesmo tempo, não suporta outros, como o uso de bancos de dados externos (além do próprio sistema de banco de dados NoSQL da Deta), máquinas virtuais personalizadas, etc.
|
||||
|
||||
Você pode ler mais detalhes na <a href="https://docs.deta.sh/docs/micros/about/" class="external-link" target="_blank">documentação da Deta</a> para ver se é a escolha certa para você.
|
||||
@@ -434,7 +434,6 @@ Usados por Pydantic:
|
||||
Usados por Starlette:
|
||||
|
||||
* <a href="https://requests.readthedocs.io" target="_blank"><code>requests</code></a> - Necessário se você quiser utilizar o `TestClient`.
|
||||
* <a href="https://github.com/Tinche/aiofiles" target="_blank"><code>aiofiles</code></a> - Necessário se você quiser utilizar o `FileResponse` ou `StaticFiles`.
|
||||
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Necessário se você quiser utilizar a configuração padrão de templates.
|
||||
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - Necessário se você quiser suporte com <abbr title="converte uma string que chega de uma requisição HTTP para dados Python">"parsing"</abbr> de formulário, com `request.form()`.
|
||||
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Necessário para suporte a `SessionMiddleware`.
|
||||
|
||||
94
docs/pt/docs/tutorial/background-tasks.md
Normal file
@@ -0,0 +1,94 @@
|
||||
# Tarefas em segundo plano
|
||||
|
||||
Você pode definir tarefas em segundo plano a serem executadas _ após _ retornar uma resposta.
|
||||
|
||||
Isso é útil para operações que precisam acontecer após uma solicitação, mas que o cliente realmente não precisa esperar a operação ser concluída para receber a resposta.
|
||||
|
||||
Isso inclui, por exemplo:
|
||||
|
||||
- Envio de notificações por email após a realização de uma ação:
|
||||
- Como conectar-se a um servidor de e-mail e enviar um e-mail tende a ser "lento" (vários segundos), você pode retornar a resposta imediatamente e enviar a notificação por e-mail em segundo plano.
|
||||
- Processando dados:
|
||||
- Por exemplo, digamos que você receba um arquivo que deve passar por um processo lento, você pode retornar uma resposta de "Aceito" (HTTP 202) e processá-lo em segundo plano.
|
||||
|
||||
## Usando `BackgroundTasks`
|
||||
|
||||
Primeiro, importe `BackgroundTasks` e defina um parâmetro em sua _função de operação de caminho_ com uma declaração de tipo de `BackgroundTasks`:
|
||||
|
||||
```Python hl_lines="1 13"
|
||||
{!../../../docs_src/background_tasks/tutorial001.py!}
|
||||
```
|
||||
|
||||
O **FastAPI** criará o objeto do tipo `BackgroundTasks` para você e o passará como esse parâmetro.
|
||||
|
||||
## Criar uma função de tarefa
|
||||
|
||||
Crie uma função a ser executada como tarefa em segundo plano.
|
||||
|
||||
É apenas uma função padrão que pode receber parâmetros.
|
||||
|
||||
Pode ser uma função `async def` ou `def` normal, o **FastAPI** saberá como lidar com isso corretamente.
|
||||
|
||||
Nesse caso, a função de tarefa gravará em um arquivo (simulando o envio de um e-mail).
|
||||
|
||||
E como a operação de gravação não usa `async` e `await`, definimos a função com `def` normal:
|
||||
|
||||
```Python hl_lines="6-9"
|
||||
{!../../../docs_src/background_tasks/tutorial001.py!}
|
||||
```
|
||||
|
||||
## Adicionar a tarefa em segundo plano
|
||||
|
||||
Dentro de sua _função de operação de caminho_, passe sua função de tarefa para o objeto _tarefas em segundo plano_ com o método `.add_task()`:
|
||||
|
||||
```Python hl_lines="14"
|
||||
{!../../../docs_src/background_tasks/tutorial001.py!}
|
||||
```
|
||||
|
||||
`.add_task()` recebe como argumentos:
|
||||
|
||||
- Uma função de tarefa a ser executada em segundo plano (`write_notification`).
|
||||
- Qualquer sequência de argumentos que deve ser passada para a função de tarefa na ordem (`email`).
|
||||
- Quaisquer argumentos nomeados que devem ser passados para a função de tarefa (`mensagem = "alguma notificação"`).
|
||||
|
||||
## Injeção de dependência
|
||||
|
||||
Usar `BackgroundTasks` também funciona com o sistema de injeção de dependência, você pode declarar um parâmetro do tipo `BackgroundTasks` em vários níveis: em uma _função de operação de caminho_, em uma dependência (confiável), em uma subdependência, etc.
|
||||
|
||||
O **FastAPI** sabe o que fazer em cada caso e como reutilizar o mesmo objeto, de forma que todas as tarefas em segundo plano sejam mescladas e executadas em segundo plano posteriormente:
|
||||
|
||||
```Python hl_lines="13 15 22 25"
|
||||
{!../../../docs_src/background_tasks/tutorial002.py!}
|
||||
```
|
||||
|
||||
Neste exemplo, as mensagens serão gravadas no arquivo `log.txt` _após_ o envio da resposta.
|
||||
|
||||
Se houver uma consulta na solicitação, ela será gravada no log em uma tarefa em segundo plano.
|
||||
|
||||
E então outra tarefa em segundo plano gerada na _função de operação de caminho_ escreverá uma mensagem usando o parâmetro de caminho `email`.
|
||||
|
||||
## Detalhes técnicos
|
||||
|
||||
A classe `BackgroundTasks` vem diretamente de <a href="https://www.starlette.io/background/" class="external-link" target="_blank">`starlette.background`</a>.
|
||||
|
||||
Ela é importada/incluída diretamente no FastAPI para que você possa importá-la do `fastapi` e evitar a importação acidental da alternativa `BackgroundTask` (sem o `s` no final) de `starlette.background`.
|
||||
|
||||
Usando apenas `BackgroundTasks` (e não `BackgroundTask`), é então possível usá-la como um parâmetro de _função de operação de caminho_ e deixar o **FastAPI** cuidar do resto para você, assim como ao usar o objeto `Request` diretamente.
|
||||
|
||||
Ainda é possível usar `BackgroundTask` sozinho no FastAPI, mas você deve criar o objeto em seu código e retornar uma Starlette `Response` incluindo-o.
|
||||
|
||||
Você pode ver mais detalhes na <a href="https://www.starlette.io/background/" class="external-link" target="_blank"> documentação oficiais da Starlette para tarefas em segundo plano </a>.
|
||||
|
||||
## Ressalva
|
||||
|
||||
Se você precisa realizar cálculos pesados em segundo plano e não necessariamente precisa que seja executado pelo mesmo processo (por exemplo, você não precisa compartilhar memória, variáveis, etc), você pode se beneficiar do uso de outras ferramentas maiores, como <a href="http://www.celeryproject.org/" class="external-link" target="_blank"> Celery </a>.
|
||||
|
||||
Eles tendem a exigir configurações mais complexas, um gerenciador de fila de mensagens/tarefas, como RabbitMQ ou Redis, mas permitem que você execute tarefas em segundo plano em vários processos e, especialmente, em vários servidores.
|
||||
|
||||
Para ver um exemplo, verifique os [Geradores de projeto](../project-generation.md){.internal-link target=\_blank}, todos incluem celery já configurado.
|
||||
|
||||
Mas se você precisa acessar variáveis e objetos do mesmo aplicativo **FastAPI**, ou precisa realizar pequenas tarefas em segundo plano (como enviar uma notificação por e-mail), você pode simplesmente usar `BackgroundTasks`.
|
||||
|
||||
## Recapitulando
|
||||
|
||||
Importe e use `BackgroundTasks` com parâmetros em _funções de operação de caminho_ e dependências para adicionar tarefas em segundo plano.
|
||||
165
docs/pt/docs/tutorial/body.md
Normal file
@@ -0,0 +1,165 @@
|
||||
# Corpo da Requisição
|
||||
|
||||
Quando você precisa enviar dados de um cliente (como de um navegador web) para sua API, você o envia como um **corpo da requisição**.
|
||||
|
||||
O corpo da **requisição** é a informação enviada pelo cliente para sua API. O corpo da **resposta** é a informação que sua API envia para o cliente.
|
||||
|
||||
Sua API quase sempre irá enviar um corpo na **resposta**. Mas os clientes não necessariamente precisam enviar um corpo em toda **requisição**.
|
||||
|
||||
Para declarar um corpo da **requisição**, você utiliza os modelos do <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> com todos os seus poderes e benefícios.
|
||||
|
||||
!!! info "Informação"
|
||||
Para enviar dados, você deve usar utilizar um dos métodos: `POST` (Mais comum), `PUT`, `DELETE` ou `PATCH`.
|
||||
|
||||
Enviar um corpo em uma requisição `GET` não tem um comportamento definido nas especificações, porém é suportado pelo FastAPI, apenas para casos de uso bem complexos/extremos.
|
||||
|
||||
Como é desencorajado, a documentação interativa com Swagger UI não irá mostrar a documentação para o corpo da requisição para um `GET`, e proxies que intermediarem podem não suportar o corpo da requisição.
|
||||
|
||||
## Importe o `BaseModel` do Pydantic
|
||||
|
||||
Primeiro, você precisa importar `BaseModel` do `pydantic`:
|
||||
|
||||
```Python hl_lines="4"
|
||||
{!../../../docs_src/body/tutorial001.py!}
|
||||
```
|
||||
|
||||
## Crie seu modelo de dados
|
||||
|
||||
Então você declara seu modelo de dados como uma classe que herda `BaseModel`.
|
||||
|
||||
Utilize os tipos Python padrão para todos os atributos:
|
||||
|
||||
```Python hl_lines="7-11"
|
||||
{!../../../docs_src/body/tutorial001.py!}
|
||||
```
|
||||
|
||||
Assim como quando declaramos parâmetros de consulta, quando um atributo do modelo possui um valor padrão, ele se torna opcional. Caso contrário, se torna obrigatório. Use `None` para torná-lo opcional.
|
||||
|
||||
Por exemplo, o modelo acima declara um JSON "`object`" (ou `dict` no Python) como esse:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"name": "Foo",
|
||||
"description": "Uma descrição opcional",
|
||||
"price": 45.2,
|
||||
"tax": 3.5
|
||||
}
|
||||
```
|
||||
|
||||
...como `description` e `tax` são opcionais (Com um valor padrão de `None`), esse JSON "`object`" também é válido:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"name": "Foo",
|
||||
"price": 45.2
|
||||
}
|
||||
```
|
||||
|
||||
## Declare como um parâmetro
|
||||
|
||||
Para adicionar o corpo na *função de operação de rota*, declare-o da mesma maneira que você declarou parâmetros de rota e consulta:
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!../../../docs_src/body/tutorial001.py!}
|
||||
```
|
||||
|
||||
...E declare o tipo como o modelo que você criou, `Item`.
|
||||
|
||||
## Resultados
|
||||
|
||||
Apenas com esse declaração de tipos do Python, o **FastAPI** irá:
|
||||
|
||||
* Ler o corpo da requisição como um JSON.
|
||||
* Converter os tipos correspondentes (se necessário).
|
||||
* Validar os dados.
|
||||
* Se algum dados for inválido, irá retornar um erro bem claro, indicando exatamente onde e o que está incorreto.
|
||||
* Entregar a você a informação recebida no parâmetro `item`.
|
||||
* Como você o declarou na função como do tipo `Item`, você também terá o suporte do editor (completação, etc) para todos os atributos e seus tipos.
|
||||
* Gerar um <a href="https://json-schema.org" class="external-link" target="_blank">Esquema JSON</a> com as definições do seu modelo, você também pode utilizá-lo em qualquer lugar que quiser, se fizer sentido para seu projeto.
|
||||
* Esses esquemas farão parte do esquema OpenAPI, e utilizados nas <abbr title="User Interfaces">UIs</abbr> de documentação automática.
|
||||
|
||||
## Documentação automática
|
||||
|
||||
Os esquemas JSON dos seus modelos farão parte do esquema OpenAPI gerado para sua aplicação, e aparecerão na documentação interativa da API:
|
||||
|
||||
<img src="/img/tutorial/body/image01.png">
|
||||
|
||||
E também serão utilizados em cada *função de operação de rota* que utilizá-los:
|
||||
|
||||
<img src="/img/tutorial/body/image02.png">
|
||||
|
||||
## Suporte do editor de texto:
|
||||
|
||||
No seu editor de texto, dentro da função você receberá dicas de tipos e completação em todo lugar (isso não aconteceria se você recebesse um `dict` em vez de um modelo Pydantic):
|
||||
|
||||
<img src="/img/tutorial/body/image03.png">
|
||||
|
||||
Você também poderá receber verificações de erros para operações de tipos incorretas:
|
||||
|
||||
<img src="/img/tutorial/body/image04.png">
|
||||
|
||||
Isso não é por acaso, todo o framework foi construído em volta deste design.
|
||||
|
||||
E foi imensamente testado na fase de design, antes de qualquer implementação, para garantir que funcionaria para todos os editores de texto.
|
||||
|
||||
Houveram mudanças no próprio Pydantic para que isso fosse possível.
|
||||
|
||||
As capturas de tela anteriores foram capturas no <a href="https://code.visualstudio.com" class="external-link" target="_blank">Visual Studio Code</a>.
|
||||
|
||||
Mas você terá o mesmo suporte do editor no <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> e na maioria dos editores Python:
|
||||
|
||||
<img src="/img/tutorial/body/image05.png">
|
||||
|
||||
!!! tip "Dica"
|
||||
Se você utiliza o <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> como editor, você pode utilizar o <a href="https://github.com/koxudaxi/pydantic-pycharm-plugin/" class="external-link" target="_blank">Plugin do Pydantic para o PyCharm </a>.
|
||||
|
||||
Melhora o suporte do editor para seus modelos Pydantic com::
|
||||
|
||||
* completação automática
|
||||
* verificação de tipos
|
||||
* refatoração
|
||||
* buscas
|
||||
* inspeções
|
||||
|
||||
## Use o modelo
|
||||
|
||||
Dentro da função, você pode acessar todos os atributos do objeto do modelo diretamente:
|
||||
|
||||
```Python hl_lines="21"
|
||||
{!../../../docs_src/body/tutorial002.py!}
|
||||
```
|
||||
|
||||
## Corpo da requisição + parâmetros de rota
|
||||
|
||||
Você pode declarar parâmetros de rota e corpo da requisição ao mesmo tempo.
|
||||
|
||||
O **FastAPI** irá reconhecer que os parâmetros da função que combinam com parâmetros de rota devem ser **retirados da rota**, e parâmetros da função que são declarados como modelos Pydantic sejam **retirados do corpo da requisição**.
|
||||
|
||||
```Python hl_lines="17-18"
|
||||
{!../../../docs_src/body/tutorial003.py!}
|
||||
```
|
||||
|
||||
## Corpo da requisição + parâmetros de rota + parâmetros de consulta
|
||||
|
||||
Você também pode declarar parâmetros de **corpo**, **rota** e **consulta**, ao mesmo tempo.
|
||||
|
||||
O **FastAPI** irá reconhecer cada um deles e retirar a informação do local correto.
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!../../../docs_src/body/tutorial004.py!}
|
||||
```
|
||||
|
||||
Os parâmetros da função serão reconhecidos conforme abaixo:
|
||||
|
||||
* Se o parâmetro também é declarado na **rota**, será utilizado como um parâmetro de rota.
|
||||
* Se o parâmetro é de um **tipo único** (como `int`, `float`, `str`, `bool`, etc) será interpretado como um parâmetro de **consulta**.
|
||||
* Se o parâmetro é declarado como um **modelo Pydantic**, será interpretado como o **corpo** da requisição.
|
||||
|
||||
!!! note "Observação"
|
||||
O FastAPI saberá que o valor de `q` não é obrigatório por causa do valor padrão `= None`.
|
||||
|
||||
O `Optional` em `Optional[str]` não é utilizado pelo FastAPI, mas permite ao seu editor de texto lhe dar um suporte melhor e detectar erros.
|
||||
|
||||
## Sem o Pydantic
|
||||
|
||||
Se você não quer utilizar os modelos Pydantic, você também pode utilizar o parâmetro **Body**. Veja a documentação para [Body - Parâmetros múltiplos: Valores singulares no body](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank}.
|
||||