Compare commits
269 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1876ebc779 | ||
|
|
1673b3ec11 | ||
|
|
1711403732 | ||
|
|
acab64b3c3 | ||
|
|
0a8d6871fb | ||
|
|
ca437cdfab | ||
|
|
c5be1b0550 | ||
|
|
9262fa8362 | ||
|
|
31690dda2c | ||
|
|
8b66b9ca3e | ||
|
|
975d859ac4 | ||
|
|
82775f7cd0 | ||
|
|
497e5a2422 | ||
|
|
f31ad41dda | ||
|
|
d75c69e01f | ||
|
|
f204e8010a | ||
|
|
bcabbf8b37 | ||
|
|
29df6b3e83 | ||
|
|
16f1d073db | ||
|
|
199916ac8c | ||
|
|
4bb8ac2114 | ||
|
|
a5eff3b78e | ||
|
|
277a53442b | ||
|
|
9cae3cdb09 | ||
|
|
f673e64eeb | ||
|
|
3d0f130ff3 | ||
|
|
9cbd42b13e | ||
|
|
8c593a9cc9 | ||
|
|
f3b04a6118 | ||
|
|
4fcdb31947 | ||
|
|
1bbbdb4b7f | ||
|
|
15dd12629e | ||
|
|
0f7de452dd | ||
|
|
35445828c8 | ||
|
|
ff2daa0471 | ||
|
|
e9098abe8c | ||
|
|
062107159f | ||
|
|
a38b0a7fac | ||
|
|
643291b9ca | ||
|
|
441f75a06c | ||
|
|
688d2db5e3 | ||
|
|
99a41e7f8d | ||
|
|
d71b12f323 | ||
|
|
cb5a200a7c | ||
|
|
2aaac141dd | ||
|
|
03cbdd4f74 | ||
|
|
a7e659e472 | ||
|
|
350745c545 | ||
|
|
d0e4015034 | ||
|
|
b1e691091d | ||
|
|
9b4e6751bb | ||
|
|
8082b45f24 | ||
|
|
86c459d1e8 | ||
|
|
2a91ee945d | ||
|
|
764703cc56 | ||
|
|
71ea5883cd | ||
|
|
cc51b251dd | ||
|
|
6337186ff4 | ||
|
|
88606940f5 | ||
|
|
98bb5480a5 | ||
|
|
170123a41f | ||
|
|
9262a699f2 | ||
|
|
9a87c6d8d2 | ||
|
|
f396912043 | ||
|
|
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 | ||
|
|
3efb4f7edf | ||
|
|
9c25f9615c | ||
|
|
e7158bc592 | ||
|
|
6d642ef5fb | ||
|
|
b0cd4d7e7e | ||
|
|
0a87bc88b8 | ||
|
|
062efcbb5d | ||
|
|
aa4a69f790 | ||
|
|
eb79441a7f | ||
|
|
fa5639cb35 | ||
|
|
10e3a02582 | ||
|
|
fb9c4b31b9 | ||
|
|
39dbee9d56 | ||
|
|
dd463d0dc2 | ||
|
|
461e0d4cce | ||
|
|
da69a1c4c0 | ||
|
|
a5d697b9b5 | ||
|
|
8e416875ce | ||
|
|
446d194c46 | ||
|
|
cace5a79f7 | ||
|
|
dabb4898f1 | ||
|
|
f282c0e207 | ||
|
|
146ff28d9c | ||
|
|
58ab733f19 | ||
|
|
0a61a6c865 | ||
|
|
fb1f341231 | ||
|
|
652cf4bb6b | ||
|
|
08410ca568 | ||
|
|
0d5e0ba5d5 | ||
|
|
b2c9574fc6 | ||
|
|
a859497a72 | ||
|
|
3c93e803d5 | ||
|
|
0bd8f901df | ||
|
|
864643ef76 | ||
|
|
5d80e02ae8 | ||
|
|
affe542753 | ||
|
|
8e887d7145 | ||
|
|
46cf92c55a |
8
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
@@ -8,9 +8,9 @@ body:
|
||||
Thanks for your interest in FastAPI! 🚀
|
||||
|
||||
Please follow these instructions, fill every question, and do every step. 🙏
|
||||
|
||||
|
||||
I'm asking this because answering questions and solving problems in GitHub issues is what consumes most of the time.
|
||||
|
||||
|
||||
I end up not being able to add new features, fix bugs, review pull requests, etc. as fast as I wish because I have to spend too much time handling issues.
|
||||
|
||||
All that, on top of all the incredible help provided by a bunch of community members, the [FastAPI Experts](https://fastapi.tiangolo.com/fastapi-people/#experts), that give a lot of their time to come here and help others.
|
||||
@@ -18,7 +18,7 @@ body:
|
||||
That's a lot of work they are doing, but if more FastAPI users came to help others like them just a little bit more, it would be much less effort for them (and you and me 😅).
|
||||
|
||||
By asking questions in a structured way (following this) it will be much easier to help you.
|
||||
|
||||
|
||||
And there's a high chance that you will find the solution along the way and you won't even have to submit it and wait for an answer. 😎
|
||||
|
||||
As there are too many issues with questions, I'll have to close the incomplete ones. That will allow me (and others) to focus on helping people like you that follow the whole process and help us help you. 🤓
|
||||
@@ -50,7 +50,7 @@ body:
|
||||
label: Commit to Help
|
||||
description: |
|
||||
After submitting this, I commit to one of:
|
||||
|
||||
|
||||
* Read open issues with questions until I find 2 issues where I can help someone and add a comment to help there.
|
||||
* I already hit the "watch" button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.
|
||||
* Implement a Pull Request for a confirmed bug.
|
||||
|
||||
8
.github/ISSUE_TEMPLATE/question.yml
vendored
@@ -8,9 +8,9 @@ body:
|
||||
Thanks for your interest in FastAPI! 🚀
|
||||
|
||||
Please follow these instructions, fill every question, and do every step. 🙏
|
||||
|
||||
|
||||
I'm asking this because answering questions and solving problems in GitHub issues is what consumes most of the time.
|
||||
|
||||
|
||||
I end up not being able to add new features, fix bugs, review pull requests, etc. as fast as I wish because I have to spend too much time handling issues.
|
||||
|
||||
All that, on top of all the incredible help provided by a bunch of community members, the [FastAPI Experts](https://fastapi.tiangolo.com/fastapi-people/#experts), that give a lot of their time to come here and help others.
|
||||
@@ -18,7 +18,7 @@ body:
|
||||
That's a lot of work they are doing, but if more FastAPI users came to help others like them just a little bit more, it would be much less effort for them (and you and me 😅).
|
||||
|
||||
By asking questions in a structured way (following this) it will be much easier to help you.
|
||||
|
||||
|
||||
And there's a high chance that you will find the solution along the way and you won't even have to submit it and wait for an answer. 😎
|
||||
|
||||
As there are too many issues with questions, I'll have to close the incomplete ones. That will allow me (and others) to focus on helping people like you that follow the whole process and help us help you. 🤓
|
||||
@@ -50,7 +50,7 @@ body:
|
||||
label: Commit to Help
|
||||
description: |
|
||||
After submitting this, I commit to one of:
|
||||
|
||||
|
||||
* Read open issues with questions until I find 2 issues where I can help someone and add a comment to help there.
|
||||
* I already hit the "watch" button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.
|
||||
* Implement a Pull Request for a confirmed bug.
|
||||
|
||||
@@ -48,9 +48,7 @@ if __name__ == "__main__":
|
||||
use_pr = pr
|
||||
break
|
||||
if not use_pr:
|
||||
logging.error(
|
||||
f"No PR found for hash: {event.workflow_run.head_commit.id}"
|
||||
)
|
||||
logging.error(f"No PR found for hash: {event.workflow_run.head_commit.id}")
|
||||
sys.exit(0)
|
||||
github_headers = {
|
||||
"Authorization": f"token {settings.input_token.get_secret_value()}"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import logging
|
||||
import random
|
||||
import time
|
||||
from pathlib import Path
|
||||
import random
|
||||
from typing import Dict, Optional
|
||||
|
||||
import yaml
|
||||
@@ -54,7 +54,7 @@ if __name__ == "__main__":
|
||||
)
|
||||
if pr.state == "open":
|
||||
logging.debug(f"PR is open: {pr.number}")
|
||||
label_strs = set([label.name for label in pr.get_labels()])
|
||||
label_strs = {label.name for label in pr.get_labels()}
|
||||
if lang_all_label in label_strs and awaiting_label in label_strs:
|
||||
logging.info(
|
||||
f"This PR seems to be a language translation and awaiting reviews: {pr.number}"
|
||||
|
||||
@@ -13,3 +13,5 @@ pl: 3169
|
||||
de: 3716
|
||||
id: 3717
|
||||
az: 3994
|
||||
nl: 4701
|
||||
uz: 4883
|
||||
|
||||
21
.github/actions/people/app/main.py
vendored
@@ -14,7 +14,7 @@ from pydantic import BaseModel, BaseSettings, SecretStr
|
||||
github_graphql_url = "https://api.github.com/graphql"
|
||||
|
||||
issues_query = """
|
||||
query Q($after: String) {
|
||||
query Q($after: String) {
|
||||
repository(name: "fastapi", owner: "tiangolo") {
|
||||
issues(first: 100, after: $after) {
|
||||
edges {
|
||||
@@ -47,7 +47,7 @@ query Q($after: String) {
|
||||
"""
|
||||
|
||||
prs_query = """
|
||||
query Q($after: String) {
|
||||
query Q($after: String) {
|
||||
repository(name: "fastapi", owner: "tiangolo") {
|
||||
pullRequests(first: 100, after: $after) {
|
||||
edges {
|
||||
@@ -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)
|
||||
|
||||
6
.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-docs-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-v03
|
||||
- name: Install Flit
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: python3.7 -m pip install flit
|
||||
@@ -28,7 +30,7 @@ jobs:
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: python3.7 -m flit install --deps production --extras doc
|
||||
- name: Install Material for MkDocs Insiders
|
||||
if: github.event.pull_request.head.repo.fork == false && steps.cache.outputs.cache-hit != 'true'
|
||||
if: ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false ) && steps.cache.outputs.cache-hit != 'true'
|
||||
run: pip install git+https://${{ secrets.ACTIONS_TOKEN }}@github.com/squidfunk/mkdocs-material-insiders.git
|
||||
- name: Build Docs
|
||||
run: python3.7 ./scripts/docs.py build-all
|
||||
|
||||
2
.github/workflows/latest-changes.yml
vendored
@@ -12,7 +12,7 @@ on:
|
||||
description: PR number
|
||||
required: true
|
||||
debug_enabled:
|
||||
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
|
||||
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
|
||||
required: false
|
||||
default: false
|
||||
|
||||
|
||||
2
.github/workflows/people.yml
vendored
@@ -6,7 +6,7 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
debug_enabled:
|
||||
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
|
||||
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
|
||||
required: false
|
||||
default: false
|
||||
|
||||
|
||||
2
.github/workflows/preview-docs.yml
vendored
@@ -3,7 +3,7 @@ on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- Build Docs
|
||||
types:
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
|
||||
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
|
||||
|
||||
51
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,51 @@
|
||||
# See https://pre-commit.com for more information
|
||||
# See https://pre-commit.com/hooks.html for more hooks
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.2.0
|
||||
hooks:
|
||||
- id: check-added-large-files
|
||||
- id: check-toml
|
||||
- id: check-yaml
|
||||
args:
|
||||
- --unsafe
|
||||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v2.32.1
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args:
|
||||
- --py3-plus
|
||||
- --keep-runtime-typing
|
||||
- repo: https://github.com/myint/autoflake
|
||||
rev: v1.4
|
||||
hooks:
|
||||
- id: autoflake
|
||||
args:
|
||||
- --recursive
|
||||
- --in-place
|
||||
- --remove-all-unused-imports
|
||||
- --remove-unused-variables
|
||||
- --expand-star-imports
|
||||
- --exclude
|
||||
- __init__.py
|
||||
- --remove-duplicate-keys
|
||||
- repo: https://github.com/pycqa/isort
|
||||
rev: 5.10.1
|
||||
hooks:
|
||||
- id: isort
|
||||
name: isort (python)
|
||||
- id: isort
|
||||
name: isort (cython)
|
||||
types: [cython]
|
||||
- id: isort
|
||||
name: isort (pyi)
|
||||
types: [pyi]
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 22.3.0
|
||||
hooks:
|
||||
- id: black
|
||||
ci:
|
||||
autofix_commit_msg: 🎨 [pre-commit.ci] Auto format from pre-commit.com hooks
|
||||
autoupdate_commit_msg: ⬆ [pre-commit.ci] pre-commit autoupdate
|
||||
22
README.md
@@ -48,12 +48,16 @@ The key features are:
|
||||
<!-- sponsors -->
|
||||
|
||||
<a href="https://bit.ly/2QSouzH" target="_blank" title="Jina: build neural search-as-a-service for any kind of data in just minutes."><img src="https://fastapi.tiangolo.com/img/sponsors/jina.svg"></a>
|
||||
<a href="https://cryptapi.io/" target="_blank" title="CryptAPI: Your easy to use, secure and privacy oriented payment gateway."><img src="https://fastapi.tiangolo.com/img/sponsors/cryptapi.svg"></a>
|
||||
<a href="https://classiq.link/n4s" target="_blank" title="Join the team building a new SaaS platform that will change the computing world"><img src="https://fastapi.tiangolo.com/img/sponsors/classiq.png"></a>
|
||||
<a href="https://www.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 -->
|
||||
|
||||
@@ -147,7 +151,7 @@ $ pip install "uvicorn[standard]"
|
||||
* Create a file `main.py` with:
|
||||
|
||||
```Python
|
||||
from typing import Optional
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
@@ -160,7 +164,7 @@ def read_root():
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: Optional[str] = None):
|
||||
def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
@@ -170,7 +174,7 @@ def read_item(item_id: int, q: Optional[str] = None):
|
||||
If your code uses `async` / `await`, use `async def`:
|
||||
|
||||
```Python hl_lines="9 14"
|
||||
from typing import Optional
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
@@ -183,7 +187,7 @@ async def read_root():
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
async def read_item(item_id: int, q: Optional[str] = None):
|
||||
async def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
@@ -262,7 +266,7 @@ 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 typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
from pydantic import BaseModel
|
||||
@@ -273,7 +277,7 @@ app = FastAPI()
|
||||
class Item(BaseModel):
|
||||
name: str
|
||||
price: float
|
||||
is_offer: Optional[bool] = None
|
||||
is_offer: Union[bool, None] = None
|
||||
|
||||
|
||||
@app.get("/")
|
||||
@@ -282,7 +286,7 @@ def read_root():
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: Optional[str] = None):
|
||||
def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
|
||||
|
||||
|
||||
@@ -5,13 +5,15 @@ theme:
|
||||
name: material
|
||||
custom_dir: overrides
|
||||
palette:
|
||||
- scheme: default
|
||||
- media: "(prefers-color-scheme: light)"
|
||||
scheme: default
|
||||
primary: teal
|
||||
accent: amber
|
||||
toggle:
|
||||
icon: material/lightbulb
|
||||
name: Switch to light mode
|
||||
- scheme: slate
|
||||
- media: "(prefers-color-scheme: dark)"
|
||||
scheme: slate
|
||||
primary: teal
|
||||
accent: amber
|
||||
toggle:
|
||||
@@ -29,9 +31,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 +42,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 +71,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 +101,8 @@ extra:
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fa/
|
||||
name: fa
|
||||
- link: /fr/
|
||||
name: fr - français
|
||||
- link: /id/
|
||||
@@ -106,6 +113,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.
|
||||
|
||||
@@ -27,7 +27,7 @@ Mit einer interaktiven API-Dokumentation und explorativen webbasierten Benutzers
|
||||
|
||||
Alles basiert auf **Python 3.6 Typ**-Deklarationen (dank Pydantic). Es muss keine neue Syntax gelernt werden, nur standardisiertes modernes Python.
|
||||
|
||||
|
||||
|
||||
|
||||
Wenn Sie eine kurze, zweiminütige, Auffrischung in der Benutzung von Python Typ-Deklarationen benötigen (auch wenn Sie FastAPI nicht nutzen), schauen Sie sich diese kurze Einführung an (Englisch): Python Types{.internal-link target=_blank}.
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -193,11 +193,11 @@ Mit **FastAPI** bekommen Sie alle Funktionen von **Pydantic** (da FastAPI für d
|
||||
* Gutes Zusammenspiel mit Ihrer/Ihrem **<abbr title="Integrierten Entwicklungsumgebung, ähnlich zu (Quellcode-)Editor">IDE</abbr>/<abbr title="Ein Programm, was Fehler im Quellcode sucht">linter</abbr>/Gehirn**:
|
||||
* Weil Datenstrukturen von Pydantic einfach nur Instanzen ihrer definierten Klassen sind, sollten Autovervollständigung, Linting, mypy und ihre Intuition einwandfrei funktionieren.
|
||||
* **Schnell**:
|
||||
* In <a href="https://pydantic-docs.helpmanual.io/#benchmarks-tag" class="external-link" target="_blank">Vergleichen</a> ist Pydantic schneller als jede andere getestete Bibliothek.
|
||||
* In <a href="https://pydantic-docs.helpmanual.io/benchmarks/" class="external-link" target="_blank">Vergleichen</a> ist Pydantic schneller als jede andere getestete Bibliothek.
|
||||
* Validierung von **komplexen Strukturen**:
|
||||
* Benutzung von hierachischen Pydantic Schemata, Python `typing`’s `List` und `Dict`, etc.
|
||||
* Validierungen erlauben klare und einfache Datenschemadefinition, überprüft und dokumentiert als JSON Schema.
|
||||
* Sie können stark **verschachtelte JSON** Objekte haben und diese sind trotzdem validiert und annotiert.
|
||||
* **Erweiterbar**:
|
||||
* Pydantic erlaubt die Definition von eigenen Datentypen oder sie können die Validierung mit einer `validator` dekorierten Methode erweitern..
|
||||
* Pydantic erlaubt die Definition von eigenen Datentypen oder Sie können die Validierung mit einer `validator` dekorierten Methode erweitern..
|
||||
* 100% Testabdeckung.
|
||||
|
||||
@@ -149,7 +149,7 @@ $ pip install uvicorn[standard]
|
||||
* Create a file `main.py` with:
|
||||
|
||||
```Python
|
||||
from typing import Optional
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
@@ -162,7 +162,7 @@ def read_root():
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: Optional[str] = None):
|
||||
def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
@@ -172,7 +172,7 @@ def read_item(item_id: int, q: Optional[str] = None):
|
||||
If your code uses `async` / `await`, use `async def`:
|
||||
|
||||
```Python hl_lines="9 14"
|
||||
from typing import Optional
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
@@ -185,7 +185,7 @@ async def read_root():
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
async def read_item(item_id: int, q: Optional[str] = None):
|
||||
async def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
@@ -264,7 +264,7 @@ 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 typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
from pydantic import BaseModel
|
||||
@@ -275,7 +275,7 @@ app = FastAPI()
|
||||
class Item(BaseModel):
|
||||
name: str
|
||||
price: float
|
||||
is_offer: Optional[bool] = None
|
||||
is_offer: Union[bool, None] = None
|
||||
|
||||
|
||||
@app.get("/")
|
||||
@@ -284,7 +284,7 @@ def read_root():
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: Optional[str] = None):
|
||||
def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
|
||||
|
||||
@@ -321,7 +321,7 @@ And now, go to <a href="http://127.0.0.1:8000/redoc" class="external-link" targe
|
||||
|
||||
### Recap
|
||||
|
||||
In summary, you declare **once** the types of parameters, body, etc. as function parameters.
|
||||
In summary, you declare **once** the types of parameters, body, etc. as function parameters.
|
||||
|
||||
You do that with standard modern Python types.
|
||||
|
||||
@@ -378,7 +378,7 @@ Coming back to the previous code example, **FastAPI** will:
|
||||
* As the `q` parameter is declared with `= None`, it is optional.
|
||||
* Without the `None` it would be required (as is the body in the case with `PUT`).
|
||||
* For `PUT` requests to `/items/{item_id}`, Read the body as JSON:
|
||||
* Check that it has a required attribute `name` that should be a `str`.
|
||||
* Check that it has a required attribute `name` that should be a `str`.
|
||||
* Check that it has a required attribute `price` that has to be a `float`.
|
||||
* Check that it has an optional attribute `is_offer`, that should be a `bool`, if present.
|
||||
* All this would also work for deeply nested JSON objects.
|
||||
@@ -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.
|
||||
|
||||
@@ -5,13 +5,15 @@ theme:
|
||||
name: material
|
||||
custom_dir: overrides
|
||||
palette:
|
||||
- scheme: default
|
||||
- media: "(prefers-color-scheme: light)"
|
||||
scheme: default
|
||||
primary: teal
|
||||
accent: amber
|
||||
toggle:
|
||||
icon: material/lightbulb
|
||||
name: Switch to light mode
|
||||
- scheme: slate
|
||||
- media: "(prefers-color-scheme: dark)"
|
||||
scheme: slate
|
||||
primary: teal
|
||||
accent: amber
|
||||
toggle:
|
||||
@@ -29,9 +31,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 +42,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 +72,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 +102,8 @@ extra:
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fa/
|
||||
name: fa
|
||||
- link: /fr/
|
||||
name: fr - français
|
||||
- link: /id/
|
||||
@@ -107,6 +114,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
name: pl
|
||||
- link: /pt/
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
articles:
|
||||
english:
|
||||
- author: Jean-Baptiste Rocher
|
||||
author_link: https://hashnode.com/@jibrocher
|
||||
link: https://dev.indooroutdoor.io/series/fastapi-react-poll-app
|
||||
title: Building the Poll App From Django Tutorial With FastAPI And React
|
||||
- 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 +24,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
|
||||
@@ -20,6 +36,10 @@ articles:
|
||||
author_link: https://rodrigo-arenas.medium.com/
|
||||
link: https://medium.com/analytics-vidhya/serve-a-machine-learning-model-using-sklearn-fastapi-and-docker-85aabf96729b
|
||||
title: "Serve a machine learning model using Sklearn, FastAPI and Docker"
|
||||
- author: Yashasvi Singh
|
||||
author_link: https://hashnode.com/@aUnicornDev
|
||||
link: https://aunicorndev.hashnode.dev/series/supafast-api
|
||||
title: "Building an API with FastAPI and Supabase and Deploying on Deta"
|
||||
- author: Navule Pavan Kumar Rao
|
||||
author_link: https://www.linkedin.com/in/navule/
|
||||
link: https://www.tutlinks.com/deploy-fastapi-on-ubuntu-gunicorn-caddy-2/
|
||||
@@ -27,7 +47,7 @@ articles:
|
||||
- author: Patrick Ladon
|
||||
author_link: https://dev.to/factorlive
|
||||
link: https://dev.to/factorlive/python-facebook-messenger-webhook-with-fastapi-on-glitch-4n90
|
||||
title: Python Facebook messenger webhook with FastAPI on Glitch
|
||||
title: Python Facebook messenger webhook with FastAPI on Glitch
|
||||
- author: Dom Patmore
|
||||
author_link: https://twitter.com/dompatmore
|
||||
link: https://dompatmore.com/blog/authenticate-your-fastapi-app-with-auth0
|
||||
@@ -188,11 +208,19 @@ articles:
|
||||
author_link: https://medium.com/@williamhayes
|
||||
link: https://medium.com/@williamhayes/fastapi-starlette-debug-vs-prod-5f7561db3a59
|
||||
title: FastAPI/Starlette debug vs prod
|
||||
- author: Mukul Mantosh
|
||||
author_link: https://twitter.com/MantoshMukul
|
||||
link: https://www.jetbrains.com/pycharm/guide/tutorials/fastapi-aws-kubernetes/
|
||||
title: Developing FastAPI Application using K8s & AWS
|
||||
german:
|
||||
- author: Nico Axtmann
|
||||
author_link: https://twitter.com/_nicoax
|
||||
link: https://blog.codecentric.de/2019/08/inbetriebnahme-eines-scikit-learn-modells-mit-onnx-und-fastapi/
|
||||
title: Inbetriebnahme eines scikit-learn-Modells mit ONNX und FastAPI
|
||||
- author: Felix Schürmeyer
|
||||
author_link: https://hellocoding.de/autor/felix-schuermeyer/
|
||||
link: https://hellocoding.de/blog/coding-language/python/fastapi
|
||||
title: REST-API Programmieren mittels Python und dem FastAPI Modul
|
||||
japanese:
|
||||
- author: '@bee2'
|
||||
author_link: https://qiita.com/bee2
|
||||
|
||||
@@ -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: 260
|
||||
answers: 1243
|
||||
prs: 300
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=5cad72c846b7aba2e960546af490edc7375dafc4&v=4
|
||||
url: https://github.com/tiangolo
|
||||
experts:
|
||||
- login: Kludex
|
||||
count: 299
|
||||
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,69 +29,85 @@ experts:
|
||||
count: 130
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/331403?v=4
|
||||
url: https://github.com/phy25
|
||||
- login: raphaelauv
|
||||
count: 71
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
|
||||
url: https://github.com/raphaelauv
|
||||
- login: ArcLightSlavik
|
||||
count: 68
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=81a84af39c89b898b0fbc5a04e8834f60f23e55a&v=4
|
||||
count: 71
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=b0f2c37142f4b762e41ad65dc49581813422bd71&v=4
|
||||
url: https://github.com/ArcLightSlavik
|
||||
- login: falkben
|
||||
count: 57
|
||||
count: 58
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/653031?u=0c8d8f33d87f1aa1a6488d3f02105e9abc838105&v=4
|
||||
url: https://github.com/falkben
|
||||
- login: sm-Fifteen
|
||||
count: 48
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/516999?u=437c0c5038558c67e887ccd863c1ba0f846c03da&v=4
|
||||
url: https://github.com/sm-Fifteen
|
||||
- login: raphaelauv
|
||||
count: 48
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
|
||||
url: https://github.com/raphaelauv
|
||||
- login: includeamin
|
||||
count: 38
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11836741?u=8bd5ef7e62fe6a82055e33c4c0e0a7879ff8cfb6&v=4
|
||||
url: https://github.com/includeamin
|
||||
- login: insomnes
|
||||
count: 46
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16958893?u=f8be7088d5076d963984a21f95f44e559192d912&v=4
|
||||
url: https://github.com/insomnes
|
||||
- login: Dustyposa
|
||||
count: 38
|
||||
count: 43
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4
|
||||
url: https://github.com/Dustyposa
|
||||
- login: includeamin
|
||||
count: 39
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11836741?u=8bd5ef7e62fe6a82055e33c4c0e0a7879ff8cfb6&v=4
|
||||
url: https://github.com/includeamin
|
||||
- login: 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/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: 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
|
||||
url: https://github.com/krishnardt
|
||||
- login: insomnes
|
||||
count: 30
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16958893?u=f8be7088d5076d963984a21f95f44e559192d912&v=4
|
||||
url: https://github.com/insomnes
|
||||
- login: wshayes
|
||||
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: 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/41326348?u=ba2fda6b30110411ecbf406d187907e2b420ac19&v=4
|
||||
url: https://github.com/panla
|
||||
- login: ghandic
|
||||
count: 25
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/23500353?u=e2e1d736f924d9be81e8bfc565b6d8836ba99773&v=4
|
||||
url: https://github.com/ghandic
|
||||
- login: dbanty
|
||||
count: 25
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/43723790?u=9bcce836bbce55835291c5b2ac93a4e311f4b3c3&v=4
|
||||
url: https://github.com/dbanty
|
||||
- login: 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
|
||||
url: https://github.com/SirTelemak
|
||||
- login: STeveShary
|
||||
count: 24
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5167622?u=de8f597c81d6336fcebc37b32dfd61a3f877160c&v=4
|
||||
url: https://github.com/STeveShary
|
||||
- login: acnebs
|
||||
count: 22
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9054108?u=bfd127b3e6200f4d00afd714f0fc95c2512df19b&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9054108?u=c27e50269f1ef8ea950cc6f0268c8ec5cebbe9c9&v=4
|
||||
url: https://github.com/acnebs
|
||||
- login: nsidnev
|
||||
count: 22
|
||||
@@ -105,18 +121,14 @@ experts:
|
||||
count: 19
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/24581770?v=4
|
||||
url: https://github.com/retnikt
|
||||
- login: ghandic
|
||||
- login: acidjunk
|
||||
count: 18
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/23500353?u=e2e1d736f924d9be81e8bfc565b6d8836ba99773&v=4
|
||||
url: https://github.com/ghandic
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
|
||||
url: https://github.com/acidjunk
|
||||
- login: Hultner
|
||||
count: 18
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2669034?u=115e53df959309898ad8dc9443fbb35fee71df07&v=4
|
||||
url: https://github.com/Hultner
|
||||
- login: panla
|
||||
count: 18
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/41326348?u=ba2fda6b30110411ecbf406d187907e2b420ac19&v=4
|
||||
url: https://github.com/panla
|
||||
- login: jorgerpo
|
||||
count: 17
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/12537771?u=7444d20019198e34911082780cc7ad73f2b97cb3&v=4
|
||||
@@ -125,26 +137,50 @@ experts:
|
||||
count: 17
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/28262306?u=66ee21316275ef356081c2efc4ed7a4572e690dc&v=4
|
||||
url: https://github.com/nkhitrov
|
||||
- login: adriangb
|
||||
- login: harunyasar
|
||||
count: 17
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1755071?u=81f0262df34e1460ca546fbd0c211169c2478532&v=4
|
||||
url: https://github.com/adriangb
|
||||
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: 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: acidjunk
|
||||
- login: valentin994
|
||||
count: 13
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
|
||||
url: https://github.com/acidjunk
|
||||
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
|
||||
url: https://github.com/lowercase00
|
||||
- login: zamiramir
|
||||
count: 11
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/40475662?u=e58ef61034e8d0d6a312cc956fb09b9c3332b449&v=4
|
||||
@@ -153,63 +189,35 @@ experts:
|
||||
count: 11
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8134632?v=4
|
||||
url: https://github.com/juntatalor
|
||||
- login: dstlny
|
||||
- login: n8sty
|
||||
count: 11
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/41964673?u=9f2174f9d61c15c6e3a4c9e3aeee66f711ce311f&v=4
|
||||
url: https://github.com/dstlny
|
||||
- login: valentin994
|
||||
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
|
||||
last_month_active:
|
||||
- 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/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: 13
|
||||
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: ghandic
|
||||
count: 12
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/23500353?u=e2e1d736f924d9be81e8bfc565b6d8836ba99773&v=4
|
||||
url: https://github.com/ghandic
|
||||
- login: STeveShary
|
||||
count: 8
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5167622?u=de8f597c81d6336fcebc37b32dfd61a3f877160c&v=4
|
||||
url: https://github.com/STeveShary
|
||||
- login: Honda-a
|
||||
- login: yinziyan1206
|
||||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/22759187?u=f45bd5fb17b4dca331529b8e9e5eab6122b84b8b&v=4
|
||||
url: https://github.com/Honda-a
|
||||
- login: frankie567
|
||||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1144727?u=85c025e3fcc7bd79a5665c63ee87cdf8aae13374&v=4
|
||||
url: https://github.com/frankie567
|
||||
- login: panla
|
||||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/41326348?u=ba2fda6b30110411ecbf406d187907e2b420ac19&v=4
|
||||
url: https://github.com/panla
|
||||
- login: dstlny
|
||||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/41964673?u=9f2174f9d61c15c6e3a4c9e3aeee66f711ce311f&v=4
|
||||
url: https://github.com/dstlny
|
||||
- login: trevorwang
|
||||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/121966?v=4
|
||||
url: https://github.com/trevorwang
|
||||
- login: klaa97
|
||||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/39653693?v=4
|
||||
url: https://github.com/klaa97
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/37829370?v=4
|
||||
url: https://github.com/yinziyan1206
|
||||
top_contributors:
|
||||
- login: waynerv
|
||||
count: 25
|
||||
@@ -223,6 +231,10 @@ 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
|
||||
@@ -231,25 +243,25 @@ top_contributors:
|
||||
count: 12
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11489395?u=4adb6986bf3debfc2b8216ae701f2bd47d73da7d&v=4
|
||||
url: https://github.com/mariacamilagl
|
||||
- login: jaystone776
|
||||
count: 11
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11191137?u=299205a95e9b6817a43144a48b643346a5aac5cc&v=4
|
||||
url: https://github.com/jaystone776
|
||||
- login: Smlep
|
||||
count: 9
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16785985?v=4
|
||||
url: https://github.com/Smlep
|
||||
- login: Serrones
|
||||
count: 8
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/22691749?u=4795b880e13ca33a73e52fc0ef7dc9c60c8fce47&v=4
|
||||
url: https://github.com/Serrones
|
||||
- login: 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: 6
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=f2d3d2038c55d86d7f9348f4e6c5e30191e4ee8b&v=4
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
|
||||
url: https://github.com/hard-coders
|
||||
- login: wshayes
|
||||
count: 5
|
||||
@@ -263,10 +275,6 @@ top_contributors:
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1175560?v=4
|
||||
url: https://github.com/Attsun1031
|
||||
- login: Smlep
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16785985?v=4
|
||||
url: https://github.com/Smlep
|
||||
- login: jekirl
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2546697?u=a027452387d85bd4a14834e19d716c99255fb3b7&v=4
|
||||
@@ -275,14 +283,22 @@ top_contributors:
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/805749?v=4
|
||||
url: https://github.com/jfunez
|
||||
- login: ycd
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=826f228edf0bab0d19ad1d5c4ba4df1047ccffef&v=4
|
||||
url: https://github.com/ycd
|
||||
- login: komtaki
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/39375566?u=260ad6b1a4b34c07dbfa728da5e586f16f6d1824&v=4
|
||||
url: https://github.com/komtaki
|
||||
- login: NinaHwang
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/79563565?u=1741703bd6c8f491503354b363a86e879b4c1cab&v=4
|
||||
url: https://github.com/NinaHwang
|
||||
top_reviewers:
|
||||
- login: Kludex
|
||||
count: 90
|
||||
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
|
||||
@@ -297,17 +313,29 @@ top_reviewers:
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/41147016?u=55010621aece725aa702270b54fed829b6a1fe60&v=4
|
||||
url: https://github.com/tokusumi
|
||||
- login: ycd
|
||||
count: 43
|
||||
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: 32
|
||||
count: 33
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1024932?u=bb7f8a0d6c9de4e9d0320a9f271210206e202250&v=4
|
||||
url: https://github.com/AdrianDeAnda
|
||||
- login: ArcLightSlavik
|
||||
count: 27
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=81a84af39c89b898b0fbc5a04e8834f60f23e55a&v=4
|
||||
count: 31
|
||||
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
|
||||
@@ -316,22 +344,42 @@ top_reviewers:
|
||||
count: 21
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/39375566?u=260ad6b1a4b34c07dbfa728da5e586f16f6d1824&v=4
|
||||
url: https://github.com/komtaki
|
||||
- login: cassiobotaro
|
||||
- login: yezz123
|
||||
count: 19
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3127847?u=b0a652331da17efeb85cd6e3a4969182e5004804&v=4
|
||||
url: https://github.com/cassiobotaro
|
||||
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
|
||||
url: https://github.com/hard-coders
|
||||
- login: 0417taehyun
|
||||
count: 19
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/63915557?u=47debaa860fd52c9b98c97ef357ddcec3b3fb399&v=4
|
||||
url: https://github.com/0417taehyun
|
||||
- login: zy7y
|
||||
count: 17
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/67154681?u=5d634834cc514028ea3f9115f7030b99a1f4d5a4&v=4
|
||||
url: https://github.com/zy7y
|
||||
- login: yanever
|
||||
count: 16
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/21978760?v=4
|
||||
url: https://github.com/yanever
|
||||
- login: lsglucas
|
||||
count: 16
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/61513630?u=320e43fe4dc7bc6efc64e9b8f325f8075634fd20&v=4
|
||||
url: https://github.com/lsglucas
|
||||
- login: SwftAlpc
|
||||
count: 16
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/52768429?u=6a3aa15277406520ad37f6236e89466ed44bc5b8&v=4
|
||||
url: https://github.com/SwftAlpc
|
||||
- login: hard-coders
|
||||
- login: Smlep
|
||||
count: 16
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=f2d3d2038c55d86d7f9348f4e6c5e30191e4ee8b&v=4
|
||||
url: https://github.com/hard-coders
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16785985?v=4
|
||||
url: https://github.com/Smlep
|
||||
- login: DevDae
|
||||
count: 16
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/87962045?u=08e10fa516e844934f4b3fc7c38b33c61697e4a1&v=4
|
||||
url: https://github.com/DevDae
|
||||
- login: pedabraham
|
||||
count: 15
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16860088?u=abf922a7b920bf8fdb7867d8b43e091f1e796178&v=4
|
||||
@@ -340,16 +388,8 @@ top_reviewers:
|
||||
count: 15
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/63476957?u=6c86e59b48e0394d4db230f37fc9ad4d7e2c27c7&v=4
|
||||
url: https://github.com/delhi09
|
||||
- login: Smlep
|
||||
count: 15
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16785985?v=4
|
||||
url: https://github.com/Smlep
|
||||
- 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
|
||||
@@ -372,10 +412,22 @@ top_reviewers:
|
||||
count: 10
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7887703?v=4
|
||||
url: https://github.com/maoyibo
|
||||
- login: solomein-sv
|
||||
count: 10
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/46193920?u=46acfb4aeefb1d7b9fdc5a8cbd9eb8744683c47a&v=4
|
||||
url: https://github.com/solomein-sv
|
||||
- login: graingert
|
||||
count: 9
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/413772?v=4
|
||||
url: https://github.com/graingert
|
||||
- login: PandaHun
|
||||
count: 9
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/13096845?u=646eba44db720e37d0dbe8e98e77ab534ea78a20&v=4
|
||||
url: https://github.com/PandaHun
|
||||
- login: kty4119
|
||||
count: 9
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/49435654?v=4
|
||||
url: https://github.com/kty4119
|
||||
- login: bezaca
|
||||
count: 9
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/69092910?u=4ac58eab99bd37d663f3d23551df96d4fbdbf760&v=4
|
||||
@@ -384,6 +436,22 @@ top_reviewers:
|
||||
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
|
||||
@@ -396,10 +464,6 @@ top_reviewers:
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
|
||||
url: https://github.com/raphaelauv
|
||||
- login: graingert
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/413772?v=4
|
||||
url: https://github.com/graingert
|
||||
- login: NastasiaSaby
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8245071?u=b3afd005f9e4bf080c219ef61a592b3a8004b764&v=4
|
||||
@@ -408,71 +472,23 @@ top_reviewers:
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1405026?v=4
|
||||
url: https://github.com/Mause
|
||||
- login: solomein-sv
|
||||
- login: AlexandreBiguet
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/46193920?u=46acfb4aeefb1d7b9fdc5a8cbd9eb8744683c47a&v=4
|
||||
url: https://github.com/solomein-sv
|
||||
- login: ComicShrimp
|
||||
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/43503750?u=b3e4d9a14d9a65d429ce62c566aef73178b7111d&v=4
|
||||
url: https://github.com/ComicShrimp
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/34248814?v=4
|
||||
url: https://github.com/krocdort
|
||||
- login: jovicon
|
||||
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: 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
|
||||
- login: izaguerreiro
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2241504?v=4
|
||||
url: https://github.com/izaguerreiro
|
||||
- login: aviramha
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/41201924?u=6883cc4fc13a7b2e60d4deddd4be06f9c5287880&v=4
|
||||
url: https://github.com/aviramha
|
||||
- login: Cajuteq
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/26676532?u=8ee0422981810e51480855de1c0d67b6b79cd3f2&v=4
|
||||
url: https://github.com/Cajuteq
|
||||
- login: Zxilly
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31370133?v=4
|
||||
url: https://github.com/Zxilly
|
||||
- login: dukkee
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/36825394?u=ccfd86e6a4f2d093dad6f7544cc875af67fa2df8&v=4
|
||||
url: https://github.com/dukkee
|
||||
- login: Bluenix2
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/38372706?u=c9d28aff15958d6ebf1971148bfb3154ff943c4f&v=4
|
||||
url: https://github.com/Bluenix2
|
||||
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
|
||||
|
||||
@@ -2,6 +2,15 @@ gold:
|
||||
- url: https://bit.ly/2QSouzH
|
||||
title: "Jina: build neural search-as-a-service for any kind of data in just minutes."
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/jina.svg
|
||||
- url: https://cryptapi.io/
|
||||
title: "CryptAPI: Your easy to use, secure and privacy oriented payment gateway."
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/cryptapi.svg
|
||||
- url: https://classiq.link/n4s
|
||||
title: Join the team building a new SaaS platform that will change the computing world
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/classiq.png
|
||||
- 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
|
||||
@@ -9,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/
|
||||
@@ -21,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,7 +2,11 @@ logins:
|
||||
- jina-ai
|
||||
- deta
|
||||
- investsuite
|
||||
- vimsoHQ
|
||||
- mikeckennedy
|
||||
- koaning
|
||||
- deepset-ai
|
||||
- cryptapi
|
||||
- Striveworks
|
||||
- xoflare
|
||||
- InesIvanova
|
||||
- DropbaseHQ
|
||||
- VincentParedes
|
||||
|
||||
@@ -36,7 +36,7 @@ For example, to declare another response with a status code `404` and a Pydantic
|
||||
**FastAPI** will take the Pydantic model from there, generate the `JSON Schema`, and put it in the correct place.
|
||||
|
||||
The correct place is:
|
||||
|
||||
|
||||
* In the key `content`, that has as value another JSON object (`dict`) that contains:
|
||||
* A key with the media type, e.g. `application/json`, that contains as value another JSON object, that contains:
|
||||
* A key `schema`, that has as the value the JSON Schema from the model, here's the correct place.
|
||||
|
||||
@@ -14,7 +14,7 @@ But you also want it to accept new items. And when the items didn't exist before
|
||||
|
||||
To achieve that, import `JSONResponse`, and return your content there directly, setting the `status_code` that you want:
|
||||
|
||||
```Python hl_lines="4 23"
|
||||
```Python hl_lines="4 25"
|
||||
{!../../../docs_src/additional_status_codes/tutorial001.py!}
|
||||
```
|
||||
|
||||
@@ -22,7 +22,7 @@ To achieve that, import `JSONResponse`, and return your content there directly,
|
||||
When you return a `Response` directly, like in the example above, it will be returned directly.
|
||||
|
||||
It won't be serialized with a model, etc.
|
||||
|
||||
|
||||
Make sure it has the data you want it to have, and that the values are valid JSON (if you are using `JSONResponse`).
|
||||
|
||||
!!! note "Technical Details"
|
||||
|
||||
@@ -132,8 +132,8 @@ You can probably right-click each link and select an option similar to `Save lin
|
||||
|
||||
**Swagger UI** uses the files:
|
||||
|
||||
* <a href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@3/swagger-ui-bundle.js" class="external-link" target="_blank">`swagger-ui-bundle.js`</a>
|
||||
* <a href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@3/swagger-ui.css" class="external-link" target="_blank">`swagger-ui.css`</a>
|
||||
* <a href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@4/swagger-ui-bundle.js" class="external-link" target="_blank">`swagger-ui-bundle.js`</a>
|
||||
* <a href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@4/swagger-ui.css" class="external-link" target="_blank">`swagger-ui.css`</a>
|
||||
|
||||
And **ReDoc** uses the file:
|
||||
|
||||
@@ -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. ✨
|
||||
@@ -16,11 +16,11 @@ In this section you will see how to manage authentication and authorization with
|
||||
You don't necessarily need OAuth2 scopes, and you can handle authentication and authorization however you want.
|
||||
|
||||
But OAuth2 with scopes can be nicely integrated into your API (with OpenAPI) and your API docs.
|
||||
|
||||
|
||||
Nevertheless, you still enforce those scopes, or any other security/authorization requirement, however you need, in your code.
|
||||
|
||||
In many cases, OAuth2 with scopes can be an overkill.
|
||||
|
||||
|
||||
But if you know you need it, or you are curious, keep reading.
|
||||
|
||||
## OAuth2 scopes and OpenAPI
|
||||
@@ -47,7 +47,7 @@ They are normally used to declare specific security permissions, for example:
|
||||
In OAuth2 a "scope" is just a string that declares a specific permission required.
|
||||
|
||||
It doesn't matter if it has other characters like `:` or if it is a URL.
|
||||
|
||||
|
||||
Those details are implementation specific.
|
||||
|
||||
For OAuth2 they are just strings.
|
||||
@@ -115,7 +115,7 @@ In this case, it requires the scope `me` (it could require more than one scope).
|
||||
|
||||
!!! note
|
||||
You don't necessarily need to add different scopes in different places.
|
||||
|
||||
|
||||
We are doing it here to demonstrate how **FastAPI** handles scopes declared at different levels.
|
||||
|
||||
```Python hl_lines="4 139 166"
|
||||
|
||||
@@ -182,7 +182,7 @@ Now let's check the file `sql_app/schemas.py`.
|
||||
To avoid confusion between the Peewee *models* and the Pydantic *models*, we will have the file `models.py` with the Peewee models, and the file `schemas.py` with the Pydantic models.
|
||||
|
||||
These Pydantic models define more or less a "schema" (a valid data shape).
|
||||
|
||||
|
||||
So this will help us avoiding confusion while using both.
|
||||
|
||||
### Create the Pydantic *models* / schemas
|
||||
|
||||
@@ -28,7 +28,7 @@ To override a dependency for testing, you put as a key the original dependency (
|
||||
|
||||
And then **FastAPI** will call that override instead of the original dependency.
|
||||
|
||||
```Python hl_lines="26-27 30"
|
||||
```Python hl_lines="28-29 32"
|
||||
{!../../../docs_src/dependency_testing/tutorial001.py!}
|
||||
```
|
||||
|
||||
|
||||
@@ -235,7 +235,7 @@ It was one of the first extremely fast Python frameworks based on `asyncio`. It
|
||||
|
||||
!!! check "Inspired **FastAPI** to"
|
||||
Find a way to have a crazy performance.
|
||||
|
||||
|
||||
That's why **FastAPI** is based on Starlette, as it is the fastest framework available (tested by third-party benchmarks).
|
||||
|
||||
### <a href="https://falconframework.org/" class="external-link" target="_blank">Falcon</a>
|
||||
@@ -333,7 +333,7 @@ Now APIStar is a set of tools to validate OpenAPI specifications, not a web fram
|
||||
Exist.
|
||||
|
||||
The idea of declaring multiple things (data validation, serialization and documentation) with the same Python types, that at the same time provided great editor support, was something I considered a brilliant idea.
|
||||
|
||||
|
||||
And after searching for a long time for a similar framework and testing many different alternatives, APIStar was the best option available.
|
||||
|
||||
Then APIStar stopped to exist as a server and Starlette was created, and was a new better foundation for such a system. That was the final inspiration to build **FastAPI**.
|
||||
@@ -391,7 +391,7 @@ That's one of the main things that **FastAPI** adds on top, all based on Python
|
||||
Handle all the core web parts. Adding features on top.
|
||||
|
||||
The class `FastAPI` itself inherits directly from the class `Starlette`.
|
||||
|
||||
|
||||
So, anything that you can do with Starlette, you can do it directly with **FastAPI**, as it is basically Starlette on steroids.
|
||||
|
||||
### <a href="https://www.uvicorn.org/" class="external-link" target="_blank">Uvicorn</a>
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ Successfully installed fastapi pydantic uvicorn
|
||||
* Create a `main.py` file with:
|
||||
|
||||
```Python
|
||||
from typing import Optional
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
@@ -155,7 +155,7 @@ def read_root():
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: Optional[str] = None):
|
||||
def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
@@ -350,7 +350,7 @@ If your FastAPI is a single file, for example, `main.py` without an `./app` dire
|
||||
Then you would just have to change the corresponding paths to copy the file inside the `Dockerfile`:
|
||||
|
||||
```{ .dockerfile .annotate hl_lines="10 13" }
|
||||
FROM python:3.9
|
||||
FROM python:3.9
|
||||
|
||||
WORKDIR /code
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ You can install an ASGI compatible server with:
|
||||
|
||||
!!! tip
|
||||
By adding the `standard`, Uvicorn will install and use some recommended extra dependencies.
|
||||
|
||||
|
||||
That including `uvloop`, the high-performance drop-in replacement for `asyncio`, that provides the big concurrency performance boost.
|
||||
|
||||
=== "Hypercorn"
|
||||
@@ -59,7 +59,7 @@ You can install an ASGI compatible server with:
|
||||
|
||||
## Run the Server Program
|
||||
|
||||
You can then your application the same way you have done in the tutorials, but without the `--reload` option, e.g.:
|
||||
You can then run your application the same way you have done in the tutorials, but without the `--reload` option, e.g.:
|
||||
|
||||
=== "Uvicorn"
|
||||
|
||||
@@ -89,7 +89,7 @@ You can then your application the same way you have done in the tutorials, but w
|
||||
Remember to remove the `--reload` option if you were using it.
|
||||
|
||||
The `--reload` option consumes much more resources, is more unstable, etc.
|
||||
|
||||
|
||||
It helps a lot during **development**, but you **shouldn't** use it in **production**.
|
||||
|
||||
## Hypercorn with Trio
|
||||
|
||||
@@ -190,7 +190,7 @@ With **FastAPI** you get all of **Pydantic**'s features (as FastAPI is based on
|
||||
* Plays nicely with your **<abbr title="Integrated Development Environment, similar to a code editor">IDE</abbr>/<abbr title="A program that checks for code errors">linter</abbr>/brain**:
|
||||
* Because pydantic data structures are just instances of classes you define; auto-completion, linting, mypy and your intuition should all work properly with your validated data.
|
||||
* **Fast**:
|
||||
* in <a href="https://pydantic-docs.helpmanual.io/#benchmarks-tag" class="external-link" target="_blank">benchmarks</a> Pydantic is faster than all other tested libraries.
|
||||
* in <a href="https://pydantic-docs.helpmanual.io/benchmarks/" class="external-link" target="_blank">benchmarks</a> Pydantic is faster than all other tested libraries.
|
||||
* Validate **complex structures**:
|
||||
* Use of hierarchical Pydantic models, Python `typing`’s `List` and `Dict`, etc.
|
||||
* And validators allow complex data schemas to be clearly and easily defined, checked and documented as JSON Schema.
|
||||
|
||||
@@ -103,4 +103,4 @@
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
</mxfile>
|
||||
|
||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
@@ -274,4 +274,4 @@
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
</mxfile>
|
||||
|
||||
@@ -59,4 +59,4 @@
|
||||
</text></switch></g><rect x="670" y="1006" width="270" height="70" fill="#ffffff" stroke="#000000" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 1041px; margin-left: 671px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">someapp.example.com</span><br /></font></div></div></div></foreignObject><text x="805" y="1045" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">someapp.example.com
|
||||
</text></switch></g><rect x="670" y="1086" width="270" height="70" fill="#f5f5f5" stroke="#666666" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 1121px; margin-left: 671px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">another.example.net</span><br /></font></div></div></div></foreignObject><text x="805" y="1125" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">another.example.net
|
||||
</text></switch></g><rect x="670" y="1166" width="270" height="70" fill="#f5f5f5" stroke="#666666" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 1201px; margin-left: 671px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">onemore.example.org</span><br /></font></div></div></div></foreignObject><text x="805" y="1205" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">onemore.example.org
|
||||
</text></switch></g><rect x="430" y="1141" width="220" height="70" fill="#ffffff" stroke="#000000" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 218px; height: 1px; padding-top: 1176px; margin-left: 431px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">IP:</span><br /><span style="font-size: 24px">123.124.125.126</span><br /></font></div></div></div></foreignObject><text x="540" y="1180" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">IP:...</text></switch></g><path d="M 1045 891 L 1315 891 L 1335 931 L 1315 971 L 1045 971 L 1025 931 Z" fill="#d5e8d4" stroke="#82b366" stroke-width="3" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 308px; height: 1px; padding-top: 931px; margin-left: 1026px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><span style="font-family: "roboto" ; font-size: 24px">Decrypted request for: someapp.example.com</span></div></div></div></foreignObject><text x="1180" y="935" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Decrypted request for: someapp.example.com</text></switch></g><path d="M 990 1081 L 1010 1081 L 1010 931 L 1025 931" fill="none" stroke="#000000" stroke-width="3" stroke-miterlimit="10" pointer-events="none"/></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg>
|
||||
</text></switch></g><rect x="430" y="1141" width="220" height="70" fill="#ffffff" stroke="#000000" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 218px; height: 1px; padding-top: 1176px; margin-left: 431px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">IP:</span><br /><span style="font-size: 24px">123.124.125.126</span><br /></font></div></div></div></foreignObject><text x="540" y="1180" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">IP:...</text></switch></g><path d="M 1045 891 L 1315 891 L 1335 931 L 1315 971 L 1045 971 L 1025 931 Z" fill="#d5e8d4" stroke="#82b366" stroke-width="3" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 308px; height: 1px; padding-top: 931px; margin-left: 1026px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><span style="font-family: "roboto" ; font-size: 24px">Decrypted request for: someapp.example.com</span></div></div></div></foreignObject><text x="1180" y="935" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Decrypted request for: someapp.example.com</text></switch></g><path d="M 990 1081 L 1010 1081 L 1010 931 L 1025 931" fill="none" stroke="#000000" stroke-width="3" stroke-miterlimit="10" pointer-events="none"/></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
@@ -75,4 +75,4 @@
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
</mxfile>
|
||||
|
||||
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
@@ -107,4 +107,4 @@
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
</mxfile>
|
||||
|
||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
@@ -128,4 +128,4 @@
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
</mxfile>
|
||||
|
||||
@@ -59,4 +59,4 @@
|
||||
</text></switch></g><rect x="670" y="1006" width="270" height="70" fill="#ffffff" stroke="#000000" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 1041px; margin-left: 671px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">someapp.example.com</span><br /></font></div></div></div></foreignObject><text x="805" y="1045" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">someapp.example.com
|
||||
</text></switch></g><rect x="670" y="1086" width="270" height="70" fill="#f5f5f5" stroke="#666666" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 1121px; margin-left: 671px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">another.example.net</span><br /></font></div></div></div></foreignObject><text x="805" y="1125" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">another.example.net
|
||||
</text></switch></g><rect x="670" y="1166" width="270" height="70" fill="#f5f5f5" stroke="#666666" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 1201px; margin-left: 671px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">onemore.example.org</span><br /></font></div></div></div></foreignObject><text x="805" y="1205" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">onemore.example.org
|
||||
</text></switch></g><rect x="430" y="1141" width="220" height="70" fill="#ffffff" stroke="#000000" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 218px; height: 1px; padding-top: 1176px; margin-left: 431px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">IP:</span><br /><span style="font-size: 24px">123.124.125.126</span><br /></font></div></div></div></foreignObject><text x="540" y="1180" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">IP:...</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg>
|
||||
</text></switch></g><rect x="430" y="1141" width="220" height="70" fill="#ffffff" stroke="#000000" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 218px; height: 1px; padding-top: 1176px; margin-left: 431px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">IP:</span><br /><span style="font-size: 24px">123.124.125.126</span><br /></font></div></div></div></foreignObject><text x="540" y="1180" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">IP:...</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
@@ -149,4 +149,4 @@
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
</mxfile>
|
||||
|
||||
@@ -59,4 +59,4 @@
|
||||
</text></switch></g><rect x="670" y="1006" width="270" height="70" fill="#ffffff" stroke="#000000" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 1041px; margin-left: 671px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">someapp.example.com</span><br /></font></div></div></div></foreignObject><text x="805" y="1045" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">someapp.example.com
|
||||
</text></switch></g><rect x="670" y="1086" width="270" height="70" fill="#f5f5f5" stroke="#666666" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 1121px; margin-left: 671px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">another.example.net</span><br /></font></div></div></div></foreignObject><text x="805" y="1125" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">another.example.net
|
||||
</text></switch></g><rect x="670" y="1166" width="270" height="70" fill="#f5f5f5" stroke="#666666" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 1201px; margin-left: 671px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">onemore.example.org</span><br /></font></div></div></div></foreignObject><text x="805" y="1205" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">onemore.example.org
|
||||
</text></switch></g><rect x="430" y="1141" width="220" height="70" fill="#ffffff" stroke="#000000" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 218px; height: 1px; padding-top: 1176px; margin-left: 431px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">IP:</span><br /><span style="font-size: 24px">123.124.125.126</span><br /></font></div></div></div></foreignObject><text x="540" y="1180" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">IP:...</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg>
|
||||
</text></switch></g><rect x="430" y="1141" width="220" height="70" fill="#ffffff" stroke="#000000" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 218px; height: 1px; padding-top: 1176px; margin-left: 431px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">IP:</span><br /><span style="font-size: 24px">123.124.125.126</span><br /></font></div></div></div></foreignObject><text x="540" y="1180" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">IP:...</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
@@ -163,4 +163,4 @@
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
</mxfile>
|
||||
|
||||
@@ -59,4 +59,4 @@
|
||||
</text></switch></g><rect x="670" y="1006" width="270" height="70" fill="#ffffff" stroke="#000000" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 1041px; margin-left: 671px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">someapp.example.com</span><br /></font></div></div></div></foreignObject><text x="805" y="1045" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">someapp.example.com
|
||||
</text></switch></g><rect x="670" y="1086" width="270" height="70" fill="#f5f5f5" stroke="#666666" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 1121px; margin-left: 671px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">another.example.net</span><br /></font></div></div></div></foreignObject><text x="805" y="1125" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">another.example.net
|
||||
</text></switch></g><rect x="670" y="1166" width="270" height="70" fill="#f5f5f5" stroke="#666666" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 1201px; margin-left: 671px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">onemore.example.org</span><br /></font></div></div></div></foreignObject><text x="805" y="1205" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">onemore.example.org
|
||||
</text></switch></g><rect x="430" y="1141" width="220" height="70" fill="#ffffff" stroke="#000000" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 218px; height: 1px; padding-top: 1176px; margin-left: 431px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">IP:</span><br /><span style="font-size: 24px">123.124.125.126</span><br /></font></div></div></div></foreignObject><text x="540" y="1180" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">IP:...</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg>
|
||||
</text></switch></g><rect x="430" y="1141" width="220" height="70" fill="#ffffff" stroke="#000000" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 218px; height: 1px; padding-top: 1176px; margin-left: 431px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">IP:</span><br /><span style="font-size: 24px">123.124.125.126</span><br /></font></div></div></div></foreignObject><text x="540" y="1180" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">IP:...</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
@@ -180,4 +180,4 @@
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
</mxfile>
|
||||
|
||||
@@ -59,4 +59,4 @@
|
||||
</text></switch></g><rect x="670" y="1006" width="270" height="70" fill="#ffffff" stroke="#000000" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 1041px; margin-left: 671px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">someapp.example.com</span><br /></font></div></div></div></foreignObject><text x="805" y="1045" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">someapp.example.com
|
||||
</text></switch></g><rect x="670" y="1086" width="270" height="70" fill="#f5f5f5" stroke="#666666" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 1121px; margin-left: 671px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">another.example.net</span><br /></font></div></div></div></foreignObject><text x="805" y="1125" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">another.example.net
|
||||
</text></switch></g><rect x="670" y="1166" width="270" height="70" fill="#f5f5f5" stroke="#666666" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 1201px; margin-left: 671px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">onemore.example.org</span><br /></font></div></div></div></foreignObject><text x="805" y="1205" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">onemore.example.org
|
||||
</text></switch></g><rect x="430" y="1141" width="220" height="70" fill="#ffffff" stroke="#000000" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 218px; height: 1px; padding-top: 1176px; margin-left: 431px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">IP:</span><br /><span style="font-size: 24px">123.124.125.126</span><br /></font></div></div></div></foreignObject><text x="540" y="1180" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">IP:...</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg>
|
||||
</text></switch></g><rect x="430" y="1141" width="220" height="70" fill="#ffffff" stroke="#000000" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 218px; height: 1px; padding-top: 1176px; margin-left: 431px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">IP:</span><br /><span style="font-size: 24px">123.124.125.126</span><br /></font></div></div></div></foreignObject><text x="540" y="1180" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">IP:...</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
@@ -200,4 +200,4 @@
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
</mxfile>
|
||||
|
||||
@@ -59,4 +59,4 @@
|
||||
</text></switch></g><rect x="670" y="1006" width="270" height="70" fill="#ffffff" stroke="#000000" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 1041px; margin-left: 671px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">someapp.example.com</span><br /></font></div></div></div></foreignObject><text x="805" y="1045" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">someapp.example.com
|
||||
</text></switch></g><rect x="670" y="1086" width="270" height="70" fill="#f5f5f5" stroke="#666666" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 1121px; margin-left: 671px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">another.example.net</span><br /></font></div></div></div></foreignObject><text x="805" y="1125" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">another.example.net
|
||||
</text></switch></g><rect x="670" y="1166" width="270" height="70" fill="#f5f5f5" stroke="#666666" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 1201px; margin-left: 671px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">onemore.example.org</span><br /></font></div></div></div></foreignObject><text x="805" y="1205" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">onemore.example.org
|
||||
</text></switch></g><rect x="430" y="1141" width="220" height="70" fill="#ffffff" stroke="#000000" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 218px; height: 1px; padding-top: 1176px; margin-left: 431px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">IP:</span><br /><span style="font-size: 24px">123.124.125.126</span><br /></font></div></div></div></foreignObject><text x="540" y="1180" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">IP:...</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg>
|
||||
</text></switch></g><rect x="430" y="1141" width="220" height="70" fill="#ffffff" stroke="#000000" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 218px; height: 1px; padding-top: 1176px; margin-left: 431px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">IP:</span><br /><span style="font-size: 24px">123.124.125.126</span><br /></font></div></div></div></foreignObject><text x="540" y="1180" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">IP:...</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
@@ -214,4 +214,4 @@
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
</mxfile>
|
||||
|
||||
@@ -59,4 +59,4 @@
|
||||
</text></switch></g><rect x="670" y="1006" width="270" height="70" fill="#ffffff" stroke="#000000" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 1041px; margin-left: 671px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">someapp.example.com</span><br /></font></div></div></div></foreignObject><text x="805" y="1045" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">someapp.example.com
|
||||
</text></switch></g><rect x="670" y="1086" width="270" height="70" fill="#f5f5f5" stroke="#666666" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 1121px; margin-left: 671px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">another.example.net</span><br /></font></div></div></div></foreignObject><text x="805" y="1125" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">another.example.net
|
||||
</text></switch></g><rect x="670" y="1166" width="270" height="70" fill="#f5f5f5" stroke="#666666" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 1201px; margin-left: 671px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #333333; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">onemore.example.org</span><br /></font></div></div></div></foreignObject><text x="805" y="1205" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">onemore.example.org
|
||||
</text></switch></g><rect x="430" y="1141" width="220" height="70" fill="#ffffff" stroke="#000000" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 218px; height: 1px; padding-top: 1176px; margin-left: 431px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">IP:</span><br /><span style="font-size: 24px">123.124.125.126</span><br /></font></div></div></div></foreignObject><text x="540" y="1180" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">IP:...</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg>
|
||||
</text></switch></g><rect x="430" y="1141" width="220" height="70" fill="#ffffff" stroke="#000000" stroke-width="3" pointer-events="none"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 218px; height: 1px; padding-top: 1176px; margin-left: 431px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: none; white-space: normal; word-wrap: normal; "><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">IP:</span><br /><span style="font-size: 24px">123.124.125.126</span><br /></font></div></div></div></foreignObject><text x="540" y="1180" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">IP:...</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
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 |
1375
docs/en/docs/img/sponsors/cryptapi-banner.svg
Normal file
|
After Width: | Height: | Size: 131 KiB |
1216
docs/en/docs/img/sponsors/cryptapi.svg
Normal file
|
After Width: | Height: | Size: 108 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 |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
@@ -40,4 +40,4 @@
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
</mxfile>
|
||||
|
||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 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,7 +148,7 @@ $ pip install "uvicorn[standard]"
|
||||
* Create a file `main.py` with:
|
||||
|
||||
```Python
|
||||
from typing import Optional
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
@@ -161,7 +161,7 @@ def read_root():
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: Optional[str] = None):
|
||||
def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
@@ -171,7 +171,7 @@ def read_item(item_id: int, q: Optional[str] = None):
|
||||
If your code uses `async` / `await`, use `async def`:
|
||||
|
||||
```Python hl_lines="9 14"
|
||||
from typing import Optional
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
@@ -184,7 +184,7 @@ async def read_root():
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
async def read_item(item_id: int, q: Optional[str] = None):
|
||||
async def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
@@ -263,7 +263,7 @@ 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 typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
from pydantic import BaseModel
|
||||
@@ -274,7 +274,7 @@ app = FastAPI()
|
||||
class Item(BaseModel):
|
||||
name: str
|
||||
price: float
|
||||
is_offer: Optional[bool] = None
|
||||
is_offer: Union[bool, None] = None
|
||||
|
||||
|
||||
@app.get("/")
|
||||
@@ -283,7 +283,7 @@ def read_root():
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: Optional[str] = None):
|
||||
def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
|
||||
|
||||
|
||||
@@ -72,14 +72,14 @@ class Termynal {
|
||||
* Initialise the widget, get lines, clear container and start animation.
|
||||
*/
|
||||
init() {
|
||||
/**
|
||||
/**
|
||||
* Calculates width and height of Termynal container.
|
||||
* If container is empty and lines are dynamically loaded, defaults to browser `auto` or CSS.
|
||||
*/
|
||||
*/
|
||||
const containerStyle = getComputedStyle(this.container);
|
||||
this.container.style.width = containerStyle.width !== '0px' ?
|
||||
this.container.style.width = containerStyle.width !== '0px' ?
|
||||
containerStyle.width : undefined;
|
||||
this.container.style.minHeight = containerStyle.height !== '0px' ?
|
||||
this.container.style.minHeight = containerStyle.height !== '0px' ?
|
||||
containerStyle.height : undefined;
|
||||
|
||||
this.container.setAttribute('data-termynal', '');
|
||||
@@ -138,7 +138,7 @@ class Termynal {
|
||||
restart.innerHTML = "restart ↻"
|
||||
return restart
|
||||
}
|
||||
|
||||
|
||||
generateFinish() {
|
||||
const finish = document.createElement('a')
|
||||
finish.onclick = (e) => {
|
||||
@@ -215,7 +215,7 @@ class Termynal {
|
||||
|
||||
/**
|
||||
* Converts line data objects into line elements.
|
||||
*
|
||||
*
|
||||
* @param {Object[]} lineData - Dynamically loaded lines.
|
||||
* @param {Object} line - Line data object.
|
||||
* @returns {Element[]} - Array of line elements.
|
||||
@@ -231,7 +231,7 @@ class Termynal {
|
||||
|
||||
/**
|
||||
* Helper function for generating attributes string.
|
||||
*
|
||||
*
|
||||
* @param {Object} line - Line data object.
|
||||
* @returns {string} - String of attributes.
|
||||
*/
|
||||
|
||||
@@ -29,7 +29,7 @@ Calling this program outputs:
|
||||
John Doe
|
||||
```
|
||||
|
||||
The function does the following:
|
||||
The function does the following:
|
||||
|
||||
* Takes a `first_name` and `last_name`.
|
||||
* Converts the first letter of each one to upper case with `title()`.
|
||||
@@ -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,112 @@ 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!}
|
||||
```
|
||||
|
||||
#### Using `Union` or `Optional`
|
||||
|
||||
If you are using a Python version below 3.10, here's a tip from my very **subjective** point of view:
|
||||
|
||||
* 🚨 Avoid using `Optional[SomeType]`
|
||||
* Instead ✨ **use `Union[SomeType, None]`** ✨.
|
||||
|
||||
Both are equivalent and underneath they are the same, but I would recommend `Union` instead of `Optional` because the word "**optional**" would seem to imply that the value is optional, and it actually means "it can be `None`", even if it's not optional and is still required.
|
||||
|
||||
I think `Union[str, SomeType]` is more explicit about what it means.
|
||||
|
||||
It's just about the words and names. But those words can affect how you and your teammates think about the code.
|
||||
|
||||
As an example, let's take this function:
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!../../../docs_src/python_types/tutorial009c.py!}
|
||||
```
|
||||
|
||||
The parameter `name` is defined as `Optional[str]`, but it is **not optional**, you cannot call the function without the parameter:
|
||||
|
||||
```Python
|
||||
say_hi() # Oh, no, this throws an error! 😱
|
||||
```
|
||||
|
||||
The `name` parameter is **still required** (not *optional*) because it doesn't have a default value. Still, `name` accepts `None` as the value:
|
||||
|
||||
```Python
|
||||
say_hi(name=None) # This works, None is valid 🎉
|
||||
```
|
||||
|
||||
The good news is, once you are on Python 3.10 you won't have to worry about that, as you will be able to simply use `|` to define unions of types:
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!../../../docs_src/python_types/tutorial009c_py310.py!}
|
||||
```
|
||||
|
||||
And then you won't have to worry about names like `Optional` and `Union`. 😎
|
||||
|
||||
#### 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 +434,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>.
|
||||
@@ -288,6 +461,9 @@ Taken from the official Pydantic docs:
|
||||
|
||||
You will see a lot more of all this in practice in the [Tutorial - User Guide](tutorial/index.md){.internal-link target=_blank}.
|
||||
|
||||
!!! tip
|
||||
Pydantic has a special behavior when you use `Optional` or `Union[Something, None]` without a default value, you can read more about it in the Pydantic docs about <a href="https://pydantic-docs.helpmanual.io/usage/models/#required-optional-fields" class="external-link" target="_blank">Required Optional fields</a>.
|
||||
|
||||
## Type hints in **FastAPI**
|
||||
|
||||
**FastAPI** takes advantage of these type hints to do several things.
|
||||
|
||||
@@ -2,6 +2,413 @@
|
||||
|
||||
## Latest Changes
|
||||
|
||||
|
||||
## 0.78.0
|
||||
|
||||
### Features
|
||||
|
||||
* ✨ Add support for omitting `...` as default value when declaring required parameters with:
|
||||
|
||||
* `Path()`
|
||||
* `Query()`
|
||||
* `Header()`
|
||||
* `Cookie()`
|
||||
* `Body()`
|
||||
* `Form()`
|
||||
* `File()`
|
||||
|
||||
New docs at [Tutorial - Query Parameters and String Validations - Make it required](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#make-it-required). PR [#4906](https://github.com/tiangolo/fastapi/pull/4906) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
Up to now, declaring a required parameter while adding additional validation or metadata needed using `...` (Ellipsis).
|
||||
|
||||
For example:
|
||||
|
||||
```Python
|
||||
from fastapi import Cookie, FastAPI, Header, Path, Query
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def main(
|
||||
item_id: int = Path(default=..., gt=0),
|
||||
query: str = Query(default=..., max_length=10),
|
||||
session: str = Cookie(default=..., min_length=3),
|
||||
x_trace: str = Header(default=..., title="Tracing header"),
|
||||
):
|
||||
return {"message": "Hello World"}
|
||||
```
|
||||
|
||||
...all these parameters are required because the default value is `...` (Ellipsis).
|
||||
|
||||
But now it's possible and supported to just omit the default value, as would be done with Pydantic fields, and the parameters would still be required.
|
||||
|
||||
✨ For example, this is now supported:
|
||||
|
||||
```Python
|
||||
from fastapi import Cookie, FastAPI, Header, Path, Query
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def main(
|
||||
item_id: int = Path(gt=0),
|
||||
query: str = Query(max_length=10),
|
||||
session: str = Cookie(min_length=3),
|
||||
x_trace: str = Header(title="Tracing header"),
|
||||
):
|
||||
return {"message": "Hello World"}
|
||||
```
|
||||
|
||||
To declare parameters as optional (not required), you can set a default value as always, for example using `None`:
|
||||
|
||||
```Python
|
||||
from typing import Union
|
||||
from fastapi import Cookie, FastAPI, Header, Path, Query
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def main(
|
||||
item_id: int = Path(gt=0),
|
||||
query: Union[str, None] = Query(default=None, max_length=10),
|
||||
session: Union[str, None] = Cookie(default=None, min_length=3),
|
||||
x_trace: Union[str, None] = Header(default=None, title="Tracing header"),
|
||||
):
|
||||
return {"message": "Hello World"}
|
||||
```
|
||||
|
||||
### Docs
|
||||
|
||||
* 📝 Add docs recommending `Union` over `Optional` and migrate source examples. New docs at [Python Types Intro - Using `Union` or `Optional`](https://fastapi.tiangolo.com/python-types/#using-union-or-optional). PR [#4908](https://github.com/tiangolo/fastapi/pull/4908) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 🎨 Fix default value as set in tutorial for Path Operations Advanced Configurations. PR [#4899](https://github.com/tiangolo/fastapi/pull/4899) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 📝 Add documentation for redefined path operations. PR [#4864](https://github.com/tiangolo/fastapi/pull/4864) by [@madkinsz](https://github.com/madkinsz).
|
||||
* 📝 Updates links for Celery documentation. PR [#4736](https://github.com/tiangolo/fastapi/pull/4736) by [@sammyzord](https://github.com/sammyzord).
|
||||
* ✏ Fix example code with sets in tutorial for body nested models. PR [#3030](https://github.com/tiangolo/fastapi/pull/3030) by [@hitrust](https://github.com/hitrust).
|
||||
* ✏ Fix links to Pydantic docs. PR [#4670](https://github.com/tiangolo/fastapi/pull/4670) by [@kinuax](https://github.com/kinuax).
|
||||
* 📝 Update docs about Swagger UI self-hosting with newer source links. PR [#4813](https://github.com/tiangolo/fastapi/pull/4813) by [@Kastakin](https://github.com/Kastakin).
|
||||
* 📝 Add link to external article: Building the Poll App From Django Tutorial With FastAPI And React. PR [#4778](https://github.com/tiangolo/fastapi/pull/4778) by [@jbrocher](https://github.com/jbrocher).
|
||||
* 📝 Add OpenAPI warning to "Body - Fields" docs with extra schema extensions. PR [#4846](https://github.com/tiangolo/fastapi/pull/4846) by [@ml-evs](https://github.com/ml-evs).
|
||||
|
||||
### Translations
|
||||
|
||||
* 🌐 Fix code examples in Japanese translation for `docs/ja/docs/tutorial/testing.md`. PR [#4623](https://github.com/tiangolo/fastapi/pull/4623) by [@hirotoKirimaru](https://github.com/hirotoKirimaru).
|
||||
|
||||
### Internal
|
||||
|
||||
* ♻ Refactor dict value extraction to minimize key lookups `fastapi/utils.py`. PR [#3139](https://github.com/tiangolo/fastapi/pull/3139) by [@ShahriyarR](https://github.com/ShahriyarR).
|
||||
* ✅ Add tests for required nonable parameters and body fields. PR [#4907](https://github.com/tiangolo/fastapi/pull/4907) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 👷 Fix installing Material for MkDocs Insiders in CI. PR [#4897](https://github.com/tiangolo/fastapi/pull/4897) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 👷 Add pre-commit CI instead of custom GitHub Action. PR [#4896](https://github.com/tiangolo/fastapi/pull/4896) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 👷 Add pre-commit GitHub Action workflow. PR [#4895](https://github.com/tiangolo/fastapi/pull/4895) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 📝 Add dark mode auto switch to docs based on OS preference. PR [#4869](https://github.com/tiangolo/fastapi/pull/4869) by [@ComicShrimp](https://github.com/ComicShrimp).
|
||||
* 🔥 Remove un-used old pending tests, already covered in other places. PR [#4891](https://github.com/tiangolo/fastapi/pull/4891) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 🔧 Add Python formatting hooks to pre-commit. PR [#4890](https://github.com/tiangolo/fastapi/pull/4890) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 🔧 Add pre-commit with first config and first formatting pass. PR [#4888](https://github.com/tiangolo/fastapi/pull/4888) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 👷 Disable CI installing Material for MkDocs in forks. PR [#4410](https://github.com/tiangolo/fastapi/pull/4410) by [@dolfinus](https://github.com/dolfinus).
|
||||
|
||||
## 0.77.1
|
||||
|
||||
### Upgrades
|
||||
|
||||
* ⬆ Upgrade Starlette from 0.19.0 to 0.19.1. PR [#4819](https://github.com/tiangolo/fastapi/pull/4819) by [@Kludex](https://github.com/Kludex).
|
||||
|
||||
### Docs
|
||||
|
||||
* 📝 Add link to german article: REST-API Programmieren mittels Python und dem FastAPI Modul. PR [#4624](https://github.com/tiangolo/fastapi/pull/4624) by [@fschuermeyer](https://github.com/fschuermeyer).
|
||||
* 📝 Add external link: PyCharm Guide to FastAPI. PR [#4512](https://github.com/tiangolo/fastapi/pull/4512) by [@mukulmantosh](https://github.com/mukulmantosh).
|
||||
* 📝 Add external link to article: Building an API with FastAPI and Supabase and Deploying on Deta. PR [#4440](https://github.com/tiangolo/fastapi/pull/4440) by [@aUnicornDev](https://github.com/aUnicornDev).
|
||||
* ✏ Fix small typo in `docs/en/docs/tutorial/security/first-steps.md`. PR [#4515](https://github.com/tiangolo/fastapi/pull/4515) by [@KikoIlievski](https://github.com/KikoIlievski).
|
||||
|
||||
### Translations
|
||||
|
||||
* 🌐 Add Polish translation for `docs/pl/docs/tutorial/index.md`. PR [#4516](https://github.com/tiangolo/fastapi/pull/4516) by [@MKaczkow](https://github.com/MKaczkow).
|
||||
* ✏ Fix typo in deployment. PR [#4629](https://github.com/tiangolo/fastapi/pull/4629) by [@raisulislam541](https://github.com/raisulislam541).
|
||||
* 🌐 Add Portuguese translation for `docs/pt/docs/help-fastapi.md`. PR [#4583](https://github.com/tiangolo/fastapi/pull/4583) by [@mateusjs](https://github.com/mateusjs).
|
||||
|
||||
### Internal
|
||||
|
||||
* 🔧 Add notifications in issue for Uzbek translations. PR [#4884](https://github.com/tiangolo/fastapi/pull/4884) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
## 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. 🤩
|
||||
|
||||
### Fixes
|
||||
|
||||
* 🐛 Fix JSON Schema for dataclasses, supporting the fixes in Pydantic 1.9. PR [#4272](https://github.com/tiangolo/fastapi/pull/4272) by [@PrettyWood](https://github.com/PrettyWood).
|
||||
|
||||
### Translations
|
||||
|
||||
* 🌐 Add Korean translation for `docs/tutorial/request-forms-and-files.md`. PR [#3744](https://github.com/tiangolo/fastapi/pull/3744) by [@NinaHwang](https://github.com/NinaHwang).
|
||||
* 🌐 Add Korean translation for `docs/tutorial/request-files.md`. PR [#3743](https://github.com/tiangolo/fastapi/pull/3743) by [@NinaHwang](https://github.com/NinaHwang).
|
||||
* 🌐 Add portuguese translation for `docs/tutorial/query-params-str-validations.md`. PR [#3965](https://github.com/tiangolo/fastapi/pull/3965) by [@leandrodesouzadev](https://github.com/leandrodesouzadev).
|
||||
* 🌐 Add Korean translation for `docs/tutorial/response-status-code.md`. PR [#3742](https://github.com/tiangolo/fastapi/pull/3742) by [@NinaHwang](https://github.com/NinaHwang).
|
||||
* 🌐 Add Korean translation for Tutorial - JSON Compatible Encoder. PR [#3152](https://github.com/tiangolo/fastapi/pull/3152) by [@NEONKID](https://github.com/NEONKID).
|
||||
* 🌐 Add Korean translation for Tutorial - Path Parameters and Numeric Validations. PR [#2432](https://github.com/tiangolo/fastapi/pull/2432) by [@hard-coders](https://github.com/hard-coders).
|
||||
* 🌐 Add Korean translation for `docs/ko/docs/deployment/versions.md`. PR [#4121](https://github.com/tiangolo/fastapi/pull/4121) by [@DevDae](https://github.com/DevDae).
|
||||
* 🌐 Fix Korean translation for `docs/ko/docs/tutorial/index.md`. PR [#4193](https://github.com/tiangolo/fastapi/pull/4193) by [@kimjaeyoonn](https://github.com/kimjaeyoonn).
|
||||
* 🔧 Add CryptAPI sponsor. PR [#4264](https://github.com/tiangolo/fastapi/pull/4264) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 📝 Update `docs/tutorial/dependencies/classes-as-dependencies`: Add type of query parameters in a description of `Classes as dependencies`. PR [#4015](https://github.com/tiangolo/fastapi/pull/4015) by [@0417taehyun](https://github.com/0417taehyun).
|
||||
* 🌐 Add French translation for Tutorial - First steps. PR [#3455](https://github.com/tiangolo/fastapi/pull/3455) by [@Smlep](https://github.com/Smlep).
|
||||
* 🌐 Add French translation for `docs/tutorial/path-params.md`. PR [#3548](https://github.com/tiangolo/fastapi/pull/3548) by [@Smlep](https://github.com/Smlep).
|
||||
* 🌐 Add French translation for `docs/tutorial/query-params.md`. PR [#3556](https://github.com/tiangolo/fastapi/pull/3556) by [@Smlep](https://github.com/Smlep).
|
||||
* 🌐 Add Turkish translation for `docs/python-types.md`. PR [#3926](https://github.com/tiangolo/fastapi/pull/3926) by [@BilalAlpaslan](https://github.com/BilalAlpaslan).
|
||||
|
||||
### Internal
|
||||
|
||||
* 👥 Update FastAPI People. PR [#4274](https://github.com/tiangolo/fastapi/pull/4274) by [@github-actions[bot]](https://github.com/apps/github-actions).
|
||||
|
||||
## 0.70.0
|
||||
|
||||
This release just upgrades Starlette to the latest version, `0.16.0`, which includes several bug fixes and some small breaking changes.
|
||||
|
||||
These last **three consecutive releases** are independent so that you can **migrate gradually**:
|
||||
|
||||
* First to FastAPI `0.68.2`, with no breaking changes, but upgrading all the sub-dependencies.
|
||||
* Next to FastAPI `0.69.0`, which upgrades Starlette to `0.15.0`, with AnyIO support, and a higher chance of having breaking changes in your code.
|
||||
* Finally to FastAPI `0.70.0`, just upgrading Starlette to the latest version `0.16.0` with additional bug fixes.
|
||||
|
||||
This way, in case there was a breaking change for your code in one of the releases, you can still benefit from the previous upgrades. ✨
|
||||
|
||||
### Breaking Changes - Upgrade
|
||||
|
||||
* ⬆️ Upgrade Starlette to 0.16.0. PR [#4016](https://github.com/tiangolo/fastapi/pull/4016) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
Also upgrades the ranges of optional dependencies:
|
||||
|
||||
* `"jinja2 >=2.11.2,<4.0.0"`
|
||||
* `"itsdangerous >=1.1.0,<3.0.0"`
|
||||
|
||||
## 0.69.0
|
||||
|
||||
### Breaking Changes - Upgrade
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -81,7 +89,7 @@ You can see more details in <a href="https://www.starlette.io/background/" class
|
||||
|
||||
## Caveat
|
||||
|
||||
If you need to perform heavy background computation and you don't necessarily need it to be run by the same process (for example, you don't need to share memory, variables, etc), you might benefit from using other bigger tools like <a href="https://docs.celeryproject.org" class="external-link" target="_blank">Celery</a>.
|
||||
If you need to perform heavy background computation and you don't necessarily need it to be run by the same process (for example, you don't need to share memory, variables, etc), you might benefit from using other bigger tools like <a href="https://docs.celeryq.dev" class="external-link" target="_blank">Celery</a>.
|
||||
|
||||
They tend to require more complex configurations, a message/job queue manager, like RabbitMQ or Redis, but they allow you to run background tasks in multiple processes, and especially, in multiple servers.
|
||||
|
||||
|
||||
@@ -334,7 +334,7 @@ from app.routers import items, users
|
||||
```Python
|
||||
from .routers import items, users
|
||||
```
|
||||
|
||||
|
||||
The second version is an "absolute import":
|
||||
|
||||
```Python
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -41,6 +57,10 @@ You can declare extra information in `Field`, `Query`, `Body`, etc. And it will
|
||||
|
||||
You will learn more about adding extra information later in the docs, when learning to declare examples.
|
||||
|
||||
!!! warning
|
||||
Extra keys passed to `Field` will also be present in the resulting OpenAPI schema for your application.
|
||||
As these keys may not necessarily be part of the OpenAPI specification, some OpenAPI tools, for example [the OpenAPI validator](https://validator.swagger.io/), may not work with your generated schema.
|
||||
|
||||
## Recap
|
||||
|
||||
You can use Pydantic's `Field` to declare extra validations and metadata for model attributes.
|
||||
|
||||
@@ -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="22"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10 and above"
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
In this case, **FastAPI** will expect a body like:
|
||||
|
||||
|
||||
```JSON
|
||||
{
|
||||
"item": {
|
||||
@@ -104,19 +126,32 @@ Of course, you can also declare additional query parameters whenever you need, a
|
||||
As, by default, singular values are interpreted as query parameters, you don't have to explicitly add a `Query`, you can just do:
|
||||
|
||||
```Python
|
||||
q: Optional[str] = None
|
||||
q: Union[str, None] = 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="27"
|
||||
{!> ../../../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.
|
||||
|
||||
|
||||
## Embed a single body parameter
|
||||
|
||||
Let's say you only have a single `item` body parameter from a Pydantic model `Item`.
|
||||
@@ -126,14 +161,22 @@ By default, **FastAPI** will then expect its body directly.
|
||||
But if you want it to expect a JSON with a key `item` and inside of it the model contents, as it does when you declare extra body parameters, you can use the special `Body` parameter `embed`:
|
||||
|
||||
```Python
|
||||
item: Item = Body(..., embed=True)
|
||||
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.
|
||||
@@ -228,7 +366,7 @@ In this case, you would accept any `dict` as long as it has `int` keys with `flo
|
||||
But Pydantic has automatic data conversion.
|
||||
|
||||
This means that, even though your API clients can only send strings as keys, as long as those strings contain pure integers, Pydantic will convert them and validate them.
|
||||
|
||||
|
||||
And the `dict` you receive as `weights` will actually have `int` keys and `float` values.
|
||||
|
||||
## Recap
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -114,7 +138,7 @@ But you would get the same editor support with <a href="https://www.jetbrains.co
|
||||
If you use <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> as your editor, you can use the <a href="https://github.com/koxudaxi/pydantic-pycharm-plugin/" class="external-link" target="_blank">Pydantic PyCharm Plugin</a>.
|
||||
|
||||
It improves editor support for Pydantic models, with:
|
||||
|
||||
|
||||
* auto-completion
|
||||
* type checks
|
||||
* refactoring
|
||||
@@ -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:
|
||||
|
||||
@@ -158,7 +206,7 @@ The function parameters will be recognized as follows:
|
||||
!!! note
|
||||
FastAPI will know that the value of `q` is not required because of the default value `= None`.
|
||||
|
||||
The `Optional` in `Optional[str]` is not used by FastAPI, but will allow your editor to give you better support and detect errors.
|
||||
The `Union` in `Union[str, None]` is not used by FastAPI, but will allow your editor to give you better support and detect errors.
|
||||
|
||||
## Without Pydantic
|
||||
|
||||
|
||||
@@ -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,29 +79,53 @@ 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="9"
|
||||
{!> ../../../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.
|
||||
|
||||
In both cases, it will have:
|
||||
|
||||
* an optional `q` query parameter.
|
||||
* a `skip` query parameter, with a default of `0`.
|
||||
* a `limit` query parameter, with a default of `100`.
|
||||
* An optional `q` query parameter that is a `str`.
|
||||
* A `skip` query parameter that is an `int`, with a default of `0`.
|
||||
* A `limit` query parameter that is an `int`, with a default of `100`.
|
||||
|
||||
In both cases the data will be converted, validated, documented on the OpenAPI schema, etc.
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ To do this, use `yield` instead of `return`, and write the extra steps after.
|
||||
!!! note "Technical Details"
|
||||
Any function that is valid to use with:
|
||||
|
||||
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager" class="external-link" target="_blank">`@contextlib.contextmanager`</a> or
|
||||
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager" class="external-link" target="_blank">`@contextlib.contextmanager`</a> or
|
||||
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager" class="external-link" target="_blank">`@contextlib.asynccontextmanager`</a>
|
||||
|
||||
would be valid to use as a **FastAPI** dependency.
|
||||
@@ -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
|
||||
|
||||
@@ -205,7 +207,7 @@ You can also use them inside of **FastAPI** dependencies with `yield` by using
|
||||
!!! tip
|
||||
Another way to create a context manager is with:
|
||||
|
||||
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager" class="external-link" target="_blank">`@contextlib.contextmanager`</a> or
|
||||
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager" class="external-link" target="_blank">`@contextlib.contextmanager`</a> or
|
||||
* <a href="https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager" class="external-link" target="_blank">`@contextlib.asynccontextmanager`</a>
|
||||
|
||||
using them to decorate a function with a single `yield`.
|
||||
|
||||
@@ -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-11"
|
||||
{!> ../../../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="15 20"
|
||||
{!> ../../../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="22"
|
||||
{!> ../../../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`.
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ Here are some of the additional data types you can use:
|
||||
* `datetime.timedelta`:
|
||||
* A Python `datetime.timedelta`.
|
||||
* In requests and responses will be represented as a `float` of total seconds.
|
||||
* Pydantic also allows representing it as a "ISO 8601 time diff encoding", <a href="https://pydantic-docs.helpmanual.io/#json-serialisation" class="external-link" target="_blank">see the docs for more info</a>.
|
||||
* Pydantic also allows representing it as a "ISO 8601 time diff encoding", <a href="https://pydantic-docs.helpmanual.io/usage/exporting_models/#json_encoders" class="external-link" target="_blank">see the docs for more info</a>.
|
||||
* `frozenset`:
|
||||
* In requests and responses, treated the same as a `set`:
|
||||
* In requests, a list will be read, eliminating duplicates and converting it to a `set`.
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -163,7 +163,7 @@ path -> item_id
|
||||
!!! warning
|
||||
These are technical details that you might skip if it's not important for you now.
|
||||
|
||||
`RequestValidationError` is a sub-class of Pydantic's <a href="https://pydantic-docs.helpmanual.io/#error-handling" class="external-link" target="_blank">`ValidationError`</a>.
|
||||
`RequestValidationError` is a sub-class of Pydantic's <a href="https://pydantic-docs.helpmanual.io/usage/models/#error-handling" class="external-link" target="_blank">`ValidationError`</a>.
|
||||
|
||||
**FastAPI** uses it so that, if you use a Pydantic model in `response_model`, and your data has an error, you will see the error in your log.
|
||||
|
||||
@@ -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!}
|
||||
|
||||