Compare commits
179 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4721405ef7 | ||
|
|
8066f85b3f | ||
|
|
2ffb08d0bc | ||
|
|
d1805ef466 | ||
|
|
41d774ed6d | ||
|
|
836ac56203 | ||
|
|
a01c2ca3dd | ||
|
|
6553243dbf | ||
|
|
fdc713428e | ||
|
|
60343161ea | ||
|
|
586de94ca1 | ||
|
|
56bc75372f | ||
|
|
4842dfadcf | ||
|
|
cfc06a3a3d | ||
|
|
c812b42293 | ||
|
|
68ce5b37dc | ||
|
|
0dc9a377dc | ||
|
|
d82700c96d | ||
|
|
fafe670db6 | ||
|
|
47342cdd18 | ||
|
|
e76dd3e70d | ||
|
|
e5f3d6a5eb | ||
|
|
7217f167d4 | ||
|
|
762ede2bec | ||
|
|
a3b1478221 | ||
|
|
41ff599d4b | ||
|
|
b1f27c96c4 | ||
|
|
4c401aef0f | ||
|
|
c7dad1bb59 | ||
|
|
0ef164e1ee | ||
|
|
fd6a78cbfe | ||
|
|
fa7474b2e8 | ||
|
|
2f0541f17a | ||
|
|
804a0a90cf | ||
|
|
847befdc1d | ||
|
|
4a7b21483b | ||
|
|
1182b36362 | ||
|
|
e17cacfee4 | ||
|
|
234cecb5bf | ||
|
|
612cbee165 | ||
|
|
223ed67682 | ||
|
|
a2a0119c14 | ||
|
|
09319d6271 | ||
|
|
a92e9c957a | ||
|
|
7505f24f2e | ||
|
|
57727fa4e0 | ||
|
|
a2aede32b4 | ||
|
|
7c66ec8a8b | ||
|
|
d47eea9bb6 | ||
|
|
74de9a7b15 | ||
|
|
3279f0ba63 | ||
|
|
428376d285 | ||
|
|
05c5ce3689 | ||
|
|
b4b39d3359 | ||
|
|
2f048f7199 | ||
|
|
2cef119cd7 | ||
|
|
dd1c2018dc | ||
|
|
e94c13ce74 | ||
|
|
b7ce10079e | ||
|
|
87d5870314 | ||
|
|
49bc3e0873 | ||
|
|
8767634932 | ||
|
|
32935103b1 | ||
|
|
395ece75aa | ||
|
|
e958d30d1d | ||
|
|
34fca99b28 | ||
|
|
3289796286 | ||
|
|
7167c77a18 | ||
|
|
ba882c10fe | ||
|
|
4ac55af283 | ||
|
|
3390a82832 | ||
|
|
f5844e76b5 | ||
|
|
32cefb9bff | ||
|
|
17e49bc9f7 | ||
|
|
df58ecdee2 | ||
|
|
6595658324 | ||
|
|
c8b729aea7 | ||
|
|
d8b8f211e8 | ||
|
|
ee96a099d8 | ||
|
|
ab03f22635 | ||
|
|
f5e2dd8025 | ||
|
|
19347bfc3c | ||
|
|
20d93fad94 | ||
|
|
58e50622de | ||
|
|
4ac8b8e443 | ||
|
|
3d162455a7 | ||
|
|
edc939eb3a | ||
|
|
4c64c15ead | ||
|
|
e3d67a150c | ||
|
|
9b14107695 | ||
|
|
57679e8370 | ||
|
|
6fe26b5689 | ||
|
|
510fa5b7fe | ||
|
|
ca8ddb2893 | ||
|
|
6dd8e567cc | ||
|
|
ae5c51afa6 | ||
|
|
19757d1859 | ||
|
|
e645a2db1b | ||
|
|
52fd0afc94 | ||
|
|
503cec5649 | ||
|
|
2c7a0aca95 | ||
|
|
8d29e494e0 | ||
|
|
4c23c0644b | ||
|
|
d189c38aaf | ||
|
|
010d44ee1b | ||
|
|
4b31beef35 | ||
|
|
61a8d6720c | ||
|
|
155fc5e24e | ||
|
|
2d35651a5a | ||
|
|
1574c96231 | ||
|
|
99ed2a227f | ||
|
|
6b72d54136 | ||
|
|
8474bae744 | ||
|
|
4d5e40190b | ||
|
|
1309f67f64 | ||
|
|
b086b6580d | ||
|
|
47c13874a0 | ||
|
|
ede2b53a0f | ||
|
|
918d96f6ad | ||
|
|
4c9ac66554 | ||
|
|
1f92ad349c | ||
|
|
8e1280bf87 | ||
|
|
5d2942f8fd | ||
|
|
ee017fdffa | ||
|
|
d5b588f246 | ||
|
|
1ecc9a1810 | ||
|
|
f0b4d590af | ||
|
|
beedcd90c7 | ||
|
|
f2b0670f04 | ||
|
|
795419ceee | ||
|
|
2c091aa0a4 | ||
|
|
68809d6f97 | ||
|
|
3c7a4b568c | ||
|
|
27618aa2e8 | ||
|
|
d057294de1 | ||
|
|
7cdee0eb63 | ||
|
|
ffb818970f | ||
|
|
5017949010 | ||
|
|
ad77d7f926 | ||
|
|
061e912ccf | ||
|
|
72c72774c5 | ||
|
|
e0961cbd1c | ||
|
|
8cc967a760 | ||
|
|
6d235d1fe1 | ||
|
|
66259ddbb5 | ||
|
|
b4535abe8f | ||
|
|
d59c27d017 | ||
|
|
5100a98ccd | ||
|
|
fe55402776 | ||
|
|
f00f0de9ca | ||
|
|
028e7cad67 | ||
|
|
50c1a928fb | ||
|
|
724060df43 | ||
|
|
490bde7169 | ||
|
|
3f5cfdc3fe | ||
|
|
f2d01d7a6a | ||
|
|
42ca1cb42d | ||
|
|
bdb32bfe03 | ||
|
|
ed1f93f803 | ||
|
|
33fa1b0927 | ||
|
|
928bb2e2ce | ||
|
|
778b909cc1 | ||
|
|
d56f02a986 | ||
|
|
60ef67a66b | ||
|
|
055cf356ca | ||
|
|
8ac8d70d52 | ||
|
|
eb1b858c4f | ||
|
|
0ef0aa55b0 | ||
|
|
0e75981bd0 | ||
|
|
1bc156482f | ||
|
|
6485c14c3b | ||
|
|
bd51832394 | ||
|
|
da21ec92cf | ||
|
|
7f3e0fe8a7 | ||
|
|
bde0316227 | ||
|
|
a73570a832 | ||
|
|
46726aa1c4 | ||
|
|
a3d881ab67 | ||
|
|
07f691ba4b |
6
.github/workflows/build-docs.yml
vendored
@@ -22,10 +22,10 @@ jobs:
|
||||
id: cache
|
||||
with:
|
||||
path: ${{ env.pythonLocation }}
|
||||
key: ${{ runner.os }}-python-docs-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-v03
|
||||
key: ${{ runner.os }}-python-docs-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml', 'requirements-docs.txt') }}-v03
|
||||
- name: Install docs extras
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: pip install .[doc]
|
||||
run: pip install -r requirements-docs.txt
|
||||
- name: Install Material for MkDocs Insiders
|
||||
if: ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false ) && steps.cache.outputs.cache-hit != 'true'
|
||||
run: pip install git+https://${{ secrets.ACTIONS_TOKEN }}@github.com/squidfunk/mkdocs-material-insiders.git
|
||||
@@ -42,7 +42,7 @@ jobs:
|
||||
with:
|
||||
publish-dir: './site'
|
||||
production-branch: master
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
github-token: ${{ secrets.FASTAPI_BUILD_DOCS_NETLIFY }}
|
||||
enable-commit-comment: false
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
|
||||
2
.github/workflows/issue-manager.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
||||
steps:
|
||||
- uses: tiangolo/issue-manager@0.4.0
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
token: ${{ secrets.FASTAPI_ISSUE_MANAGER }}
|
||||
config: >
|
||||
{
|
||||
"answered": {
|
||||
|
||||
2
.github/workflows/label-approved.yml
vendored
@@ -10,4 +10,4 @@ jobs:
|
||||
steps:
|
||||
- uses: docker://tiangolo/label-approved:0.0.2
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
token: ${{ secrets.FASTAPI_LABEL_APPROVED }}
|
||||
|
||||
4
.github/workflows/latest-changes.yml
vendored
@@ -30,11 +30,9 @@ jobs:
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}
|
||||
with:
|
||||
limit-access-to-actor: true
|
||||
token: ${{ secrets.ACTIONS_TOKEN }}
|
||||
standard_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: docker://tiangolo/latest-changes:0.0.3
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
token: ${{ secrets.FASTAPI_LATEST_CHANGES }}
|
||||
latest_changes_file: docs/en/docs/release-notes.md
|
||||
latest_changes_header: '## Latest Changes\n\n'
|
||||
debug_logs: true
|
||||
|
||||
2
.github/workflows/notify-translations.yml
vendored
@@ -19,4 +19,4 @@ jobs:
|
||||
limit-access-to-actor: true
|
||||
- uses: ./.github/actions/notify-translations
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
token: ${{ secrets.FASTAPI_NOTIFY_TRANSLATIONS }}
|
||||
|
||||
4
.github/workflows/people.yml
vendored
@@ -24,9 +24,7 @@ jobs:
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}
|
||||
with:
|
||||
limit-access-to-actor: true
|
||||
token: ${{ secrets.ACTIONS_TOKEN }}
|
||||
standard_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: ./.github/actions/people
|
||||
with:
|
||||
token: ${{ secrets.ACTIONS_TOKEN }}
|
||||
standard_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
standard_token: ${{ secrets.FASTAPI_PEOPLE }}
|
||||
|
||||
8
.github/workflows/preview-docs.yml
vendored
@@ -16,9 +16,9 @@ jobs:
|
||||
rm -rf ./site
|
||||
mkdir ./site
|
||||
- name: Download Artifact Docs
|
||||
uses: dawidd6/action-download-artifact@v2.26.0
|
||||
uses: dawidd6/action-download-artifact@v2.27.0
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
github_token: ${{ secrets.FASTAPI_PREVIEW_DOCS_DOWNLOAD_ARTIFACTS }}
|
||||
workflow: build-docs.yml
|
||||
run_id: ${{ github.event.workflow_run.id }}
|
||||
name: docs-zip
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
with:
|
||||
publish-dir: './site'
|
||||
production-deploy: false
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
github-token: ${{ secrets.FASTAPI_PREVIEW_DOCS_NETLIFY }}
|
||||
enable-commit-comment: false
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
@@ -42,5 +42,5 @@ jobs:
|
||||
- name: Comment Deploy
|
||||
uses: ./.github/actions/comment-docs-preview-in-pr
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
token: ${{ secrets.FASTAPI_PREVIEW_DOCS_COMMENT_DEPLOY }}
|
||||
deploy_url: "${{ steps.netlify.outputs.deploy-url }}"
|
||||
|
||||
11
.github/workflows/publish.yml
vendored
@@ -18,7 +18,8 @@ jobs:
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.7"
|
||||
cache: "pip"
|
||||
# Issue ref: https://github.com/actions/setup-python/issues/436
|
||||
# cache: "pip"
|
||||
cache-dependency-path: pyproject.toml
|
||||
- uses: actions/cache@v3
|
||||
id: cache
|
||||
@@ -31,16 +32,10 @@ jobs:
|
||||
- name: Build distribution
|
||||
run: python -m build
|
||||
- name: Publish
|
||||
uses: pypa/gh-action-pypi-publish@v1.6.4
|
||||
uses: pypa/gh-action-pypi-publish@v1.8.6
|
||||
with:
|
||||
password: ${{ secrets.PYPI_API_TOKEN }}
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
# - name: Notify
|
||||
# env:
|
||||
# GITTER_TOKEN: ${{ secrets.GITTER_TOKEN }}
|
||||
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# TAG: ${{ github.event.release.name }}
|
||||
# run: bash scripts/notify.sh
|
||||
|
||||
5
.github/workflows/smokeshow.yml
vendored
@@ -20,8 +20,9 @@ jobs:
|
||||
|
||||
- run: pip install smokeshow
|
||||
|
||||
- uses: dawidd6/action-download-artifact@v2.26.0
|
||||
- uses: dawidd6/action-download-artifact@v2.27.0
|
||||
with:
|
||||
github_token: ${{ secrets.FASTAPI_SMOKESHOW_DOWNLOAD_ARTIFACTS }}
|
||||
workflow: test.yml
|
||||
commit: ${{ github.event.workflow_run.head_sha }}
|
||||
|
||||
@@ -30,6 +31,6 @@ jobs:
|
||||
SMOKESHOW_GITHUB_STATUS_DESCRIPTION: Coverage {coverage-percentage}
|
||||
SMOKESHOW_GITHUB_COVERAGE_THRESHOLD: 100
|
||||
SMOKESHOW_GITHUB_CONTEXT: coverage
|
||||
SMOKESHOW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SMOKESHOW_GITHUB_TOKEN: ${{ secrets.FASTAPI_SMOKESHOW_UPLOAD }}
|
||||
SMOKESHOW_GITHUB_PR_HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
|
||||
SMOKESHOW_AUTH_KEY: ${{ secrets.SMOKESHOW_AUTH_KEY }}
|
||||
|
||||
54
.github/workflows/test.yml
vendored
@@ -5,34 +5,56 @@ on:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.11"
|
||||
# Issue ref: https://github.com/actions/setup-python/issues/436
|
||||
# cache: "pip"
|
||||
# cache-dependency-path: pyproject.toml
|
||||
- uses: actions/cache@v3
|
||||
id: cache
|
||||
with:
|
||||
path: ${{ env.pythonLocation }}
|
||||
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml', 'requirements-tests.txt') }}-test-v03
|
||||
- name: Install Dependencies
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: pip install -r requirements-tests.txt
|
||||
- name: Lint
|
||||
run: bash scripts/lint.sh
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: "pip"
|
||||
cache-dependency-path: pyproject.toml
|
||||
# Issue ref: https://github.com/actions/setup-python/issues/436
|
||||
# cache: "pip"
|
||||
# cache-dependency-path: pyproject.toml
|
||||
- uses: actions/cache@v3
|
||||
id: cache
|
||||
with:
|
||||
path: ${{ env.pythonLocation }}
|
||||
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-test-v03
|
||||
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml', 'requirements-tests.txt') }}-test-v03
|
||||
- name: Install Dependencies
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: pip install -e .[all,dev,doc,test]
|
||||
- name: Lint
|
||||
run: bash scripts/lint.sh
|
||||
run: pip install -r requirements-tests.txt
|
||||
- run: mkdir coverage
|
||||
- name: Test
|
||||
run: bash scripts/test.sh
|
||||
@@ -44,32 +66,28 @@ jobs:
|
||||
with:
|
||||
name: coverage
|
||||
path: coverage
|
||||
|
||||
coverage-combine:
|
||||
needs: [test]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.8'
|
||||
cache: "pip"
|
||||
cache-dependency-path: pyproject.toml
|
||||
|
||||
# Issue ref: https://github.com/actions/setup-python/issues/436
|
||||
# cache: "pip"
|
||||
# cache-dependency-path: pyproject.toml
|
||||
- name: Get coverage files
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: coverage
|
||||
path: coverage
|
||||
|
||||
- run: pip install coverage[toml]
|
||||
|
||||
- run: ls -la coverage
|
||||
- run: coverage combine coverage
|
||||
- run: coverage report
|
||||
- run: coverage html --show-contexts --title "Coverage for ${{ github.sha }}"
|
||||
|
||||
- name: Store coverage HTML
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
@@ -78,14 +96,10 @@ jobs:
|
||||
|
||||
# https://github.com/marketplace/actions/alls-green#why
|
||||
check: # This job does nothing and is only used for the branch protection
|
||||
|
||||
if: always()
|
||||
|
||||
needs:
|
||||
- coverage-combine
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Decide whether the needed jobs succeeded or failed
|
||||
uses: re-actors/alls-green@release/v1
|
||||
|
||||
@@ -21,24 +21,13 @@ repos:
|
||||
- --py3-plus
|
||||
- --keep-runtime-typing
|
||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||
rev: v0.0.254
|
||||
rev: v0.0.272
|
||||
hooks:
|
||||
- id: ruff
|
||||
args:
|
||||
- --fix
|
||||
- repo: https://github.com/pycqa/isort
|
||||
rev: 5.12.0
|
||||
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: 23.1.0
|
||||
rev: 23.3.0
|
||||
hooks:
|
||||
- id: black
|
||||
ci:
|
||||
|
||||
@@ -47,8 +47,8 @@ The key features are:
|
||||
<!-- sponsors -->
|
||||
|
||||
<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://platform.sh/try-it-now/?utm_source=fastapi-signup&utm_medium=banner&utm_campaign=FastAPI-signup-June-2023" target="_blank" title="Build, run and scale your apps on a modern, reliable, and secure PaaS."><img src="https://fastapi.tiangolo.com/img/sponsors/platform-sh.png"></a>
|
||||
<a href="https://www.deta.sh/?ref=fastapi" target="_blank" title="The launchpad for all your (team's) ideas"><img src="https://fastapi.tiangolo.com/img/sponsors/deta.svg"></a>
|
||||
<a href="https://www.investsuite.com/jobs" target="_blank" title="Wealthtech jobs with FastAPI"><img src="https://fastapi.tiangolo.com/img/sponsors/investsuite.svg"></a>
|
||||
<a href="https://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>
|
||||
@@ -446,7 +446,6 @@ To understand more about it, see the section <a href="https://fastapi.tiangolo.c
|
||||
|
||||
Used by Pydantic:
|
||||
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - for faster JSON <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>.
|
||||
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - for email validation.
|
||||
|
||||
Used by Starlette:
|
||||
|
||||
@@ -441,7 +441,6 @@ To understand more about it, see the section <a href="https://fastapi.tiangolo.c
|
||||
|
||||
Used by Pydantic:
|
||||
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - for faster JSON <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>.
|
||||
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - for email validation.
|
||||
|
||||
Used by Starlette:
|
||||
|
||||
@@ -40,6 +40,7 @@ nav:
|
||||
- Languages:
|
||||
- en: /
|
||||
- az: /az/
|
||||
- cs: /cs/
|
||||
- de: /de/
|
||||
- em: /em/
|
||||
- es: /es/
|
||||
@@ -51,6 +52,7 @@ nav:
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- lo: /lo/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
@@ -104,6 +106,8 @@ extra:
|
||||
name: en - English
|
||||
- link: /az/
|
||||
name: az
|
||||
- link: /cs/
|
||||
name: cs
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /em/
|
||||
@@ -126,6 +130,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /lo/
|
||||
name: lo - ພາສາລາວ
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
|
||||
473
docs/cs/docs/index.md
Normal file
@@ -0,0 +1,473 @@
|
||||
|
||||
{!../../../docs/missing-translation.md!}
|
||||
|
||||
|
||||
<p align="center">
|
||||
<a href="https://fastapi.tiangolo.com"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" alt="FastAPI"></a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<em>FastAPI framework, high performance, easy to learn, fast to code, ready for production</em>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://github.com/tiangolo/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
|
||||
<img src="https://github.com/tiangolo/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
|
||||
</a>
|
||||
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/tiangolo/fastapi" target="_blank">
|
||||
<img src="https://coverage-badge.samuelcolvin.workers.dev/tiangolo/fastapi.svg" alt="Coverage">
|
||||
</a>
|
||||
<a href="https://pypi.org/project/fastapi" target="_blank">
|
||||
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Package version">
|
||||
</a>
|
||||
<a href="https://pypi.org/project/fastapi" target="_blank">
|
||||
<img src="https://img.shields.io/pypi/pyversions/fastapi.svg?color=%2334D058" alt="Supported Python versions">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
**Documentation**: <a href="https://fastapi.tiangolo.com" target="_blank">https://fastapi.tiangolo.com</a>
|
||||
|
||||
**Source Code**: <a href="https://github.com/tiangolo/fastapi" target="_blank">https://github.com/tiangolo/fastapi</a>
|
||||
|
||||
---
|
||||
|
||||
FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.7+ based on standard Python type hints.
|
||||
|
||||
The key features are:
|
||||
|
||||
* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
|
||||
* **Fast to code**: Increase the speed to develop features by about 200% to 300%. *
|
||||
* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. *
|
||||
* **Intuitive**: Great editor support. <abbr title="also known as auto-complete, autocompletion, IntelliSense">Completion</abbr> everywhere. Less time debugging.
|
||||
* **Easy**: Designed to be easy to use and learn. Less time reading docs.
|
||||
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
|
||||
* **Robust**: Get production-ready code. With automatic interactive documentation.
|
||||
* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (previously known as Swagger) and <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
|
||||
|
||||
<small>* estimation based on tests on an internal development team, building production applications.</small>
|
||||
|
||||
## Sponsors
|
||||
|
||||
<!-- sponsors -->
|
||||
|
||||
{% if sponsors %}
|
||||
{% for sponsor in sponsors.gold -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
{% endfor -%}
|
||||
{%- for sponsor in sponsors.silver -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
<!-- /sponsors -->
|
||||
|
||||
<a href="https://fastapi.tiangolo.com/fastapi-people/#sponsors" class="external-link" target="_blank">Other sponsors</a>
|
||||
|
||||
## Opinions
|
||||
|
||||
"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/tiangolo/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_**Netflix** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Kevin Glisson, Marc Vilanova, Forest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_I’m over the moon excited about **FastAPI**. It’s so fun!_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a> podcast host</strong> <a href="https://twitter.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]_"
|
||||
|
||||
"_We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> founders - <a href="https://spacy.io" target="_blank">spaCy</a> creators</strong> <a href="https://twitter.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://twitter.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_If anyone is looking to build a production Python API, I would highly recommend **FastAPI**. It is **beautifully designed**, **simple to use** and **highly scalable**, it has become a **key component** in our API first development strategy and is driving many automations and services such as our Virtual TAC Engineer._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
## **Typer**, the FastAPI of CLIs
|
||||
|
||||
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
|
||||
|
||||
If you are building a <abbr title="Command Line Interface">CLI</abbr> app to be used in the terminal instead of a web API, check out <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>.
|
||||
|
||||
**Typer** is FastAPI's little sibling. And it's intended to be the **FastAPI of CLIs**. ⌨️ 🚀
|
||||
|
||||
## Requirements
|
||||
|
||||
Python 3.7+
|
||||
|
||||
FastAPI stands on the shoulders of giants:
|
||||
|
||||
* <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> for the web parts.
|
||||
* <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> for the data parts.
|
||||
|
||||
## Installation
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install fastapi
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
You will also need an ASGI server, for production such as <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> or <a href="https://github.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>.
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "uvicorn[standard]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## Example
|
||||
|
||||
### Create it
|
||||
|
||||
* Create a file `main.py` with:
|
||||
|
||||
```Python
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/")
|
||||
def read_root():
|
||||
return {"Hello": "World"}
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
<details markdown="1">
|
||||
<summary>Or use <code>async def</code>...</summary>
|
||||
|
||||
If your code uses `async` / `await`, use `async def`:
|
||||
|
||||
```Python hl_lines="9 14"
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/")
|
||||
async def read_root():
|
||||
return {"Hello": "World"}
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
async def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
**Note**:
|
||||
|
||||
If you don't know, check the _"In a hurry?"_ section about <a href="https://fastapi.tiangolo.com/async/#in-a-hurry" target="_blank">`async` and `await` in the docs</a>.
|
||||
|
||||
</details>
|
||||
|
||||
### Run it
|
||||
|
||||
Run the server with:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --reload
|
||||
|
||||
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
INFO: Started reloader process [28720]
|
||||
INFO: Started server process [28722]
|
||||
INFO: Waiting for application startup.
|
||||
INFO: Application startup complete.
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
<details markdown="1">
|
||||
<summary>About the command <code>uvicorn main:app --reload</code>...</summary>
|
||||
|
||||
The command `uvicorn main:app` refers to:
|
||||
|
||||
* `main`: the file `main.py` (the Python "module").
|
||||
* `app`: the object created inside of `main.py` with the line `app = FastAPI()`.
|
||||
* `--reload`: make the server restart after code changes. Only do this for development.
|
||||
|
||||
</details>
|
||||
|
||||
### Check it
|
||||
|
||||
Open your browser at <a href="http://127.0.0.1:8000/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1:8000/items/5?q=somequery</a>.
|
||||
|
||||
You will see the JSON response as:
|
||||
|
||||
```JSON
|
||||
{"item_id": 5, "q": "somequery"}
|
||||
```
|
||||
|
||||
You already created an API that:
|
||||
|
||||
* Receives HTTP requests in the _paths_ `/` and `/items/{item_id}`.
|
||||
* Both _paths_ take `GET` <em>operations</em> (also known as HTTP _methods_).
|
||||
* The _path_ `/items/{item_id}` has a _path parameter_ `item_id` that should be an `int`.
|
||||
* The _path_ `/items/{item_id}` has an optional `str` _query parameter_ `q`.
|
||||
|
||||
### Interactive API docs
|
||||
|
||||
Now go to <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||
|
||||
You will see the automatic interactive API documentation (provided by <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
|
||||
|
||||

|
||||
|
||||
### Alternative API docs
|
||||
|
||||
And now, go to <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
|
||||
|
||||
You will see the alternative automatic documentation (provided by <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>):
|
||||
|
||||

|
||||
|
||||
## Example upgrade
|
||||
|
||||
Now modify the file `main.py` to receive a body from a `PUT` request.
|
||||
|
||||
Declare the body using standard Python types, thanks to Pydantic.
|
||||
|
||||
```Python hl_lines="4 9-12 25-27"
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
from pydantic import BaseModel
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
class Item(BaseModel):
|
||||
name: str
|
||||
price: float
|
||||
is_offer: Union[bool, None] = None
|
||||
|
||||
|
||||
@app.get("/")
|
||||
def read_root():
|
||||
return {"Hello": "World"}
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
|
||||
|
||||
@app.put("/items/{item_id}")
|
||||
def update_item(item_id: int, item: Item):
|
||||
return {"item_name": item.name, "item_id": item_id}
|
||||
```
|
||||
|
||||
The server should reload automatically (because you added `--reload` to the `uvicorn` command above).
|
||||
|
||||
### Interactive API docs upgrade
|
||||
|
||||
Now go to <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||
|
||||
* The interactive API documentation will be automatically updated, including the new body:
|
||||
|
||||

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

|
||||
|
||||
* Then click on the "Execute" button, the user interface will communicate with your API, send the parameters, get the results and show them on the screen:
|
||||
|
||||

|
||||
|
||||
### Alternative API docs upgrade
|
||||
|
||||
And now, go to <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
|
||||
|
||||
* The alternative documentation will also reflect the new query parameter and body:
|
||||
|
||||

|
||||
|
||||
### Recap
|
||||
|
||||
In summary, you declare **once** the types of parameters, body, etc. as function parameters.
|
||||
|
||||
You do that with standard modern Python types.
|
||||
|
||||
You don't have to learn a new syntax, the methods or classes of a specific library, etc.
|
||||
|
||||
Just standard **Python 3.7+**.
|
||||
|
||||
For example, for an `int`:
|
||||
|
||||
```Python
|
||||
item_id: int
|
||||
```
|
||||
|
||||
or for a more complex `Item` model:
|
||||
|
||||
```Python
|
||||
item: Item
|
||||
```
|
||||
|
||||
...and with that single declaration you get:
|
||||
|
||||
* Editor support, including:
|
||||
* Completion.
|
||||
* Type checks.
|
||||
* Validation of data:
|
||||
* Automatic and clear errors when the data is invalid.
|
||||
* Validation even for deeply nested JSON objects.
|
||||
* <abbr title="also known as: serialization, parsing, marshalling">Conversion</abbr> of input data: coming from the network to Python data and types. Reading from:
|
||||
* JSON.
|
||||
* Path parameters.
|
||||
* Query parameters.
|
||||
* Cookies.
|
||||
* Headers.
|
||||
* Forms.
|
||||
* Files.
|
||||
* <abbr title="also known as: serialization, parsing, marshalling">Conversion</abbr> of output data: converting from Python data and types to network data (as JSON):
|
||||
* Convert Python types (`str`, `int`, `float`, `bool`, `list`, etc).
|
||||
* `datetime` objects.
|
||||
* `UUID` objects.
|
||||
* Database models.
|
||||
* ...and many more.
|
||||
* Automatic interactive API documentation, including 2 alternative user interfaces:
|
||||
* Swagger UI.
|
||||
* ReDoc.
|
||||
|
||||
---
|
||||
|
||||
Coming back to the previous code example, **FastAPI** will:
|
||||
|
||||
* Validate that there is an `item_id` in the path for `GET` and `PUT` requests.
|
||||
* Validate that the `item_id` is of type `int` for `GET` and `PUT` requests.
|
||||
* If it is not, the client will see a useful, clear error.
|
||||
* Check if there is an optional query parameter named `q` (as in `http://127.0.0.1:8000/items/foo?q=somequery`) for `GET` requests.
|
||||
* As the `q` parameter is declared with `= None`, it is optional.
|
||||
* Without the `None` it would be required (as is the body in the case with `PUT`).
|
||||
* For `PUT` requests to `/items/{item_id}`, Read the body as JSON:
|
||||
* Check that it has a required attribute `name` that should be a `str`.
|
||||
* Check that it has a required attribute `price` that has to be a `float`.
|
||||
* Check that it has an optional attribute `is_offer`, that should be a `bool`, if present.
|
||||
* All this would also work for deeply nested JSON objects.
|
||||
* Convert from and to JSON automatically.
|
||||
* Document everything with OpenAPI, that can be used by:
|
||||
* Interactive documentation systems.
|
||||
* Automatic client code generation systems, for many languages.
|
||||
* Provide 2 interactive documentation web interfaces directly.
|
||||
|
||||
---
|
||||
|
||||
We just scratched the surface, but you already get the idea of how it all works.
|
||||
|
||||
Try changing the line with:
|
||||
|
||||
```Python
|
||||
return {"item_name": item.name, "item_id": item_id}
|
||||
```
|
||||
|
||||
...from:
|
||||
|
||||
```Python
|
||||
... "item_name": item.name ...
|
||||
```
|
||||
|
||||
...to:
|
||||
|
||||
```Python
|
||||
... "item_price": item.price ...
|
||||
```
|
||||
|
||||
...and see how your editor will auto-complete the attributes and know their types:
|
||||
|
||||

|
||||
|
||||
For a more complete example including more features, see the <a href="https://fastapi.tiangolo.com/tutorial/">Tutorial - User Guide</a>.
|
||||
|
||||
**Spoiler alert**: the tutorial - user guide includes:
|
||||
|
||||
* Declaration of **parameters** from other different places as: **headers**, **cookies**, **form fields** and **files**.
|
||||
* How to set **validation constraints** as `maximum_length` or `regex`.
|
||||
* A very powerful and easy to use **<abbr title="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** system.
|
||||
* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth.
|
||||
* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic).
|
||||
* **GraphQL** integration with <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> and other libraries.
|
||||
* Many extra features (thanks to Starlette) as:
|
||||
* **WebSockets**
|
||||
* extremely easy tests based on HTTPX and `pytest`
|
||||
* **CORS**
|
||||
* **Cookie Sessions**
|
||||
* ...and more.
|
||||
|
||||
## Performance
|
||||
|
||||
Independent TechEmpower benchmarks show **FastAPI** applications running under Uvicorn as <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">one of the fastest Python frameworks available</a>, only below Starlette and Uvicorn themselves (used internally by FastAPI). (*)
|
||||
|
||||
To understand more about it, see the section <a href="https://fastapi.tiangolo.com/benchmarks/" class="internal-link" target="_blank">Benchmarks</a>.
|
||||
|
||||
## Optional Dependencies
|
||||
|
||||
Used by Pydantic:
|
||||
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - for faster JSON <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>.
|
||||
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - for email validation.
|
||||
|
||||
Used by Starlette:
|
||||
|
||||
* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - Required if you want to use the `TestClient`.
|
||||
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
|
||||
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`.
|
||||
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Required for `SessionMiddleware` support.
|
||||
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Required for Starlette's `SchemaGenerator` support (you probably don't need it with FastAPI).
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Required if you want to use `UJSONResponse`.
|
||||
|
||||
Used by FastAPI / Starlette:
|
||||
|
||||
* <a href="https://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - for the server that loads and serves your application.
|
||||
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - Required if you want to use `ORJSONResponse`.
|
||||
|
||||
You can install all of these with `pip install "fastapi[all]"`.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the terms of the MIT license.
|
||||
154
docs/cs/mkdocs.yml
Normal file
@@ -0,0 +1,154 @@
|
||||
site_name: FastAPI
|
||||
site_description: FastAPI framework, high performance, easy to learn, fast to code, ready for production
|
||||
site_url: https://fastapi.tiangolo.com/cs/
|
||||
theme:
|
||||
name: material
|
||||
custom_dir: overrides
|
||||
palette:
|
||||
- media: '(prefers-color-scheme: light)'
|
||||
scheme: default
|
||||
primary: teal
|
||||
accent: amber
|
||||
toggle:
|
||||
icon: material/lightbulb
|
||||
name: Switch to light mode
|
||||
- media: '(prefers-color-scheme: dark)'
|
||||
scheme: slate
|
||||
primary: teal
|
||||
accent: amber
|
||||
toggle:
|
||||
icon: material/lightbulb-outline
|
||||
name: Switch to dark mode
|
||||
features:
|
||||
- search.suggest
|
||||
- search.highlight
|
||||
- content.tabs.link
|
||||
icon:
|
||||
repo: fontawesome/brands/github-alt
|
||||
logo: https://fastapi.tiangolo.com/img/icon-white.svg
|
||||
favicon: https://fastapi.tiangolo.com/img/favicon.png
|
||||
language: cs
|
||||
repo_name: tiangolo/fastapi
|
||||
repo_url: https://github.com/tiangolo/fastapi
|
||||
edit_uri: ''
|
||||
plugins:
|
||||
- search
|
||||
- markdownextradata:
|
||||
data: data
|
||||
nav:
|
||||
- FastAPI: index.md
|
||||
- Languages:
|
||||
- en: /
|
||||
- az: /az/
|
||||
- cs: /cs/
|
||||
- de: /de/
|
||||
- es: /es/
|
||||
- fa: /fa/
|
||||
- fr: /fr/
|
||||
- he: /he/
|
||||
- hy: /hy/
|
||||
- id: /id/
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
- ru: /ru/
|
||||
- sq: /sq/
|
||||
- sv: /sv/
|
||||
- ta: /ta/
|
||||
- tr: /tr/
|
||||
- uk: /uk/
|
||||
- zh: /zh/
|
||||
markdown_extensions:
|
||||
- toc:
|
||||
permalink: true
|
||||
- markdown.extensions.codehilite:
|
||||
guess_lang: false
|
||||
- mdx_include:
|
||||
base_path: docs
|
||||
- admonition
|
||||
- codehilite
|
||||
- extra
|
||||
- pymdownx.superfences:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
- attr_list
|
||||
- md_in_html
|
||||
extra:
|
||||
analytics:
|
||||
provider: google
|
||||
property: G-YNEVN69SC3
|
||||
social:
|
||||
- icon: fontawesome/brands/github-alt
|
||||
link: https://github.com/tiangolo/fastapi
|
||||
- icon: fontawesome/brands/discord
|
||||
link: https://discord.gg/VQjSZaeJmf
|
||||
- icon: fontawesome/brands/twitter
|
||||
link: https://twitter.com/fastapi
|
||||
- icon: fontawesome/brands/linkedin
|
||||
link: https://www.linkedin.com/in/tiangolo
|
||||
- icon: fontawesome/brands/dev
|
||||
link: https://dev.to/tiangolo
|
||||
- icon: fontawesome/brands/medium
|
||||
link: https://medium.com/@tiangolo
|
||||
- icon: fontawesome/solid/globe
|
||||
link: https://tiangolo.com
|
||||
alternate:
|
||||
- link: /
|
||||
name: en - English
|
||||
- link: /az/
|
||||
name: az
|
||||
- link: /cs/
|
||||
name: cs
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fa/
|
||||
name: fa
|
||||
- link: /fr/
|
||||
name: fr - français
|
||||
- link: /he/
|
||||
name: he
|
||||
- link: /hy/
|
||||
name: hy
|
||||
- link: /id/
|
||||
name: id
|
||||
- link: /it/
|
||||
name: it - italiano
|
||||
- link: /ja/
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
name: pl
|
||||
- link: /pt/
|
||||
name: pt - português
|
||||
- link: /ru/
|
||||
name: ru - русский язык
|
||||
- link: /sq/
|
||||
name: sq - shqip
|
||||
- link: /sv/
|
||||
name: sv - svenska
|
||||
- link: /ta/
|
||||
name: ta - தமிழ்
|
||||
- link: /tr/
|
||||
name: tr - Türkçe
|
||||
- link: /uk/
|
||||
name: uk - українська мова
|
||||
- link: /zh/
|
||||
name: zh - 汉语
|
||||
extra_css:
|
||||
- https://fastapi.tiangolo.com/css/termynal.css
|
||||
- https://fastapi.tiangolo.com/css/custom.css
|
||||
extra_javascript:
|
||||
- https://fastapi.tiangolo.com/js/termynal.js
|
||||
- https://fastapi.tiangolo.com/js/custom.js
|
||||
0
docs/cs/overrides/.gitignore
vendored
Normal file
@@ -440,7 +440,6 @@ To understand more about it, see the section <a href="https://fastapi.tiangolo.c
|
||||
|
||||
Used by Pydantic:
|
||||
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - for faster JSON <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>.
|
||||
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - for email validation.
|
||||
|
||||
Used by Starlette:
|
||||
|
||||
@@ -40,6 +40,7 @@ nav:
|
||||
- Languages:
|
||||
- en: /
|
||||
- az: /az/
|
||||
- cs: /cs/
|
||||
- de: /de/
|
||||
- em: /em/
|
||||
- es: /es/
|
||||
@@ -51,6 +52,7 @@ nav:
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- lo: /lo/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
@@ -105,6 +107,8 @@ extra:
|
||||
name: en - English
|
||||
- link: /az/
|
||||
name: az
|
||||
- link: /cs/
|
||||
name: cs
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /em/
|
||||
@@ -127,6 +131,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /lo/
|
||||
name: lo - ພາສາລາວ
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
|
||||
@@ -108,7 +108,7 @@ $ python -m pip install --upgrade pip
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install -e ."[dev,doc,test]"
|
||||
$ pip install -r requirements.txt
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
@@ -51,6 +51,7 @@ nav:
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- lo: /lo/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
@@ -233,6 +234,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /lo/
|
||||
name: lo - ພາສາລາວ
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
|
||||
@@ -233,6 +233,10 @@ articles:
|
||||
link: https://medium.com/@krishnardt365/fastapi-docker-and-postgres-91943e71be92
|
||||
title: Fastapi, Docker(Docker compose) and Postgres
|
||||
german:
|
||||
- author: Marcel Sander (actidoo)
|
||||
author_link: https://www.actidoo.com
|
||||
link: https://www.actidoo.com/de/blog/python-fastapi-domain-driven-design
|
||||
title: Domain-driven Design mit Python und FastAPI
|
||||
- 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/
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
sponsors:
|
||||
- - login: jina-ai
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/60539444?v=4
|
||||
url: https://github.com/jina-ai
|
||||
- - login: armand-sauzay
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/35524799?u=56e3e944bfe62770d1709c09552d2efc6d285ca6&v=4
|
||||
url: https://github.com/armand-sauzay
|
||||
- - login: cryptapi
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/44925437?u=61369138589bc7fee6c417f3fbd50fbd38286cc4&v=4
|
||||
url: https://github.com/cryptapi
|
||||
@@ -14,9 +8,6 @@ sponsors:
|
||||
- login: ObliviousAI
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/65656077?v=4
|
||||
url: https://github.com/ObliviousAI
|
||||
- login: chaserowbotham
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/97751084?v=4
|
||||
url: https://github.com/chaserowbotham
|
||||
- - login: mikeckennedy
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2035561?u=1bb18268bcd4d9249e1f783a063c27df9a84c05b&v=4
|
||||
url: https://github.com/mikeckennedy
|
||||
@@ -26,48 +17,42 @@ sponsors:
|
||||
- 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: svix
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/80175132?v=4
|
||||
url: https://github.com/svix
|
||||
- login: databento-bot
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/98378480?u=494f679996e39427f7ddb1a7de8441b7c96fb670&v=4
|
||||
url: https://github.com/databento-bot
|
||||
- login: VincentParedes
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/103889729?v=4
|
||||
url: https://github.com/VincentParedes
|
||||
- - login: getsentry
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1396951?v=4
|
||||
url: https://github.com/getsentry
|
||||
- - login: InesIvanova
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/22920417?u=409882ec1df6dbd77455788bb383a8de223dbf6f&v=4
|
||||
url: https://github.com/InesIvanova
|
||||
- - login: vyos
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5647000?v=4
|
||||
url: https://github.com/vyos
|
||||
- login: takashi-yoneya
|
||||
- - login: takashi-yoneya
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/33813153?u=2d0522bceba0b8b69adf1f2db866503bd96f944e&v=4
|
||||
url: https://github.com/takashi-yoneya
|
||||
- login: mercedes-benz
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/34240465?v=4
|
||||
url: https://github.com/mercedes-benz
|
||||
- login: xoflare
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/74335107?v=4
|
||||
url: https://github.com/xoflare
|
||||
- login: marvin-robot
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/41086007?u=091c5cb75af363123d66f58194805a97220ee1a7&v=4
|
||||
url: https://github.com/marvin-robot
|
||||
- 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
|
||||
- - login: HiredScore
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3908850?v=4
|
||||
url: https://github.com/HiredScore
|
||||
- login: ianshan0915
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5893101?u=a178d247d882578b1d1ef214b2494e52eb28634c&v=4
|
||||
url: https://github.com/ianshan0915
|
||||
- login: Trivie
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8161763?v=4
|
||||
url: https://github.com/Trivie
|
||||
- login: Lovage-Labs
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/71685552?v=4
|
||||
url: https://github.com/Lovage-Labs
|
||||
- - login: JonasKs
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5310116?u=98a049f3e1491bffb91e1feb7e93def6881a9389&v=4
|
||||
url: https://github.com/JonasKs
|
||||
- - login: moellenbeck
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/169372?v=4
|
||||
url: https://github.com/moellenbeck
|
||||
@@ -83,12 +68,9 @@ sponsors:
|
||||
- login: tizz98
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5739698?u=f095a3659e3a8e7c69ccd822696990b521ea25f9&v=4
|
||||
url: https://github.com/tizz98
|
||||
- login: dorianturba
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9381120?u=4bfc7032a824d1ed1994aa8256dfa597c8f187ad&v=4
|
||||
url: https://github.com/dorianturba
|
||||
- login: jmaralc
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/21101214?u=b15a9f07b7cbf6c9dcdbcb6550bbd2c52f55aa50&v=4
|
||||
url: https://github.com/jmaralc
|
||||
- login: americanair
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/12281813?v=4
|
||||
url: https://github.com/americanair
|
||||
- login: mainframeindustries
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/55092103?v=4
|
||||
url: https://github.com/mainframeindustries
|
||||
@@ -132,7 +114,7 @@ sponsors:
|
||||
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
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/653031?u=ad9838e089058c9e5a0bab94c0eec7cc181e0cd0&v=4
|
||||
url: https://github.com/falkben
|
||||
- login: jqueguiner
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/690878?u=bd65cc1f228ce6455e56dfaca3ef47c33bc7c3b0&v=4
|
||||
@@ -146,24 +128,15 @@ sponsors:
|
||||
- login: mrkmcknz
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1089376?u=2b9b8a8c25c33a4f6c220095638bd821cdfd13a3&v=4
|
||||
url: https://github.com/mrkmcknz
|
||||
- login: coffeewasmyidea
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1636488?u=8e32a4f200eff54dd79cd79d55d254bfce5e946d&v=4
|
||||
url: https://github.com/coffeewasmyidea
|
||||
- login: mickaelandrieu
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1247388?u=599f6e73e452a9453f2bd91e5c3100750e731ad4&v=4
|
||||
url: https://github.com/mickaelandrieu
|
||||
- login: jonakoudijs
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1906344?u=5ca0c9a1a89b6a2ba31abe35c66bdc07af60a632&v=4
|
||||
url: https://github.com/jonakoudijs
|
||||
- login: corleyma
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2080732?u=c61f9a4bbc45a45f5d855f93e5f6e0fc8b32c468&v=4
|
||||
url: https://github.com/corleyma
|
||||
- login: andre1sk
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3148093?v=4
|
||||
url: https://github.com/andre1sk
|
||||
- login: Shark009
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3163309?u=0c6f4091b0eda05c44c390466199826e6dc6e431&v=4
|
||||
url: https://github.com/Shark009
|
||||
- login: ColliotL
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3412402?u=ca64b07ecbef2f9da1cc2cac3f37522aa4814902&v=4
|
||||
url: https://github.com/ColliotL
|
||||
- login: dblackrun
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3528486?v=4
|
||||
url: https://github.com/dblackrun
|
||||
@@ -203,69 +176,48 @@ sponsors:
|
||||
- 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=6690c5403bc1d9a1837886defdc5256e9a43b1db&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: ValentinCalomme
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7288672?u=e09758c7a36c49f0fb3574abe919cbd344fdc2d6&v=4
|
||||
url: https://github.com/ValentinCalomme
|
||||
- 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: savannahostrowski
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8949415?u=c3177aa099fb2b8c36aeba349278b77f9a8df211&v=4
|
||||
url: https://github.com/savannahostrowski
|
||||
- login: wdwinslow
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11562137?u=dc01daafb354135603a263729e3d26d939c0c452&v=4
|
||||
url: https://github.com/wdwinslow
|
||||
- login: svats2k
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/12378398?u=ecf28c19f61052e664bdfeb2391f8107d137915c&v=4
|
||||
url: https://github.com/svats2k
|
||||
- login: dannywade
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/13680237?u=418ee985bd41577b20fde81417fb2d901e875e8a&v=4
|
||||
url: https://github.com/dannywade
|
||||
- login: khadrawy
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/13686061?u=59f25ef42ecf04c22657aac4238ce0e2d3d30304&v=4
|
||||
url: https://github.com/khadrawy
|
||||
- login: pablonnaoji
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/15187159?u=7480e0eaf959e9c5dfe3a05286f2ea4588c0a3c6&v=4
|
||||
url: https://github.com/pablonnaoji
|
||||
- login: mjohnsey
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16784016?u=38fad2e6b411244560b3af99c5f5a4751bc81865&v=4
|
||||
url: https://github.com/mjohnsey
|
||||
- login: abdalla19977
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/17257234?v=4
|
||||
url: https://github.com/abdalla19977
|
||||
- login: wedwardbeck
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/19333237?u=1de4ae2bf8d59eb4c013f21d863cbe0f2010575f&v=4
|
||||
url: https://github.com/wedwardbeck
|
||||
- login: RaamEEIL
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/20320552?v=4
|
||||
url: https://github.com/RaamEEIL
|
||||
- login: Filimoa
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/21352040?u=0be845711495bbd7b756e13fcaeb8efc1ebd78ba&v=4
|
||||
url: https://github.com/Filimoa
|
||||
- login: shuheng-liu
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/22414322?u=813c45f30786c6b511b21a661def025d8f7b609e&v=4
|
||||
url: https://github.com/shuheng-liu
|
||||
- login: Pablongo24
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/24843427?u=78a6798469889d7a0690449fc667c39e13d5c6a9&v=4
|
||||
url: https://github.com/Pablongo24
|
||||
- login: Joeriksson
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/25037079?v=4
|
||||
url: https://github.com/Joeriksson
|
||||
- login: cometa-haley
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/25950317?u=cec1a3e0643b785288ae8260cc295a85ab344995&v=4
|
||||
url: https://github.com/cometa-haley
|
||||
- login: SebTota
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/25122511?v=4
|
||||
url: https://github.com/SebTota
|
||||
- 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: BrettskiPy
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/30988215?u=d8a94a67e140d5ee5427724b292cc52d8827087a&v=4
|
||||
url: https://github.com/BrettskiPy
|
||||
@@ -290,27 +242,21 @@ sponsors:
|
||||
- login: arleybri18
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/39681546?u=5c028f81324b0e8c73b3c15bc4e7b0218d2ba0c3&v=4
|
||||
url: https://github.com/arleybri18
|
||||
- login: thenickben
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/40610922?u=1e907d904041b7c91213951a3cb344cd37c14aaf&v=4
|
||||
url: https://github.com/thenickben
|
||||
- login: ybressler
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/40807730?u=41e2c00f1eebe3c402635f0325e41b4e6511462c&v=4
|
||||
url: https://github.com/ybressler
|
||||
- login: ddilidili
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/42176885?u=c0a849dde06987434653197b5f638d3deb55fc6c&v=4
|
||||
url: https://github.com/ddilidili
|
||||
- login: VictorCalderon
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/44529243?u=cea69884f826a29aff1415493405209e0706d07a&v=4
|
||||
url: https://github.com/VictorCalderon
|
||||
- login: rafsaf
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/51059348?u=f8f0d6d6e90fac39fa786228158ba7f013c74271&v=4
|
||||
url: https://github.com/rafsaf
|
||||
- login: dudikbender
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/53487583?u=3a57542938ebfd57579a0111db2b297e606d9681&v=4
|
||||
url: https://github.com/dudikbender
|
||||
- login: thisistheplace
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/57633545?u=a3f3a7f8ace8511c6c067753f6eb6aee0db11ac6&v=4
|
||||
url: https://github.com/thisistheplace
|
||||
- login: kyjoconn
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/58443406?u=a3e9c2acfb7ba62edda9334aba61cf027f41f789&v=4
|
||||
url: https://github.com/kyjoconn
|
||||
- login: A-Edge
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/59514131?v=4
|
||||
url: https://github.com/A-Edge
|
||||
@@ -320,9 +266,6 @@ sponsors:
|
||||
- login: patsatsia
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/61111267?u=3271b85f7a37b479c8d0ae0a235182e83c166edf&v=4
|
||||
url: https://github.com/patsatsia
|
||||
- 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
|
||||
@@ -341,24 +284,21 @@ sponsors:
|
||||
- login: Dagmaara
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/115501964?v=4
|
||||
url: https://github.com/Dagmaara
|
||||
- - login: Yarden-zamir
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8178413?u=ee177a8b0f87ea56747f4d96f34cd4e9604a8217&v=4
|
||||
url: https://github.com/Yarden-zamir
|
||||
- - login: pawamoy
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3999221?u=b030e4c89df2f3a36bc4710b925bdeb6745c9856&v=4
|
||||
url: https://github.com/pawamoy
|
||||
- login: linux-china
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/46711?u=cd77c65338b158750eb84dc7ff1acf3209ccfc4f&v=4
|
||||
url: https://github.com/linux-china
|
||||
- login: ddanier
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/113563?u=ed1dc79de72f93bd78581f88ebc6952b62f472da&v=4
|
||||
url: https://github.com/ddanier
|
||||
- login: jhb
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/142217?v=4
|
||||
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: slafs
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/210173?v=4
|
||||
url: https://github.com/slafs
|
||||
- login: adamghill
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/317045?u=f1349d5ffe84a19f324e204777859fbf69ddf633&v=4
|
||||
url: https://github.com/adamghill
|
||||
@@ -378,11 +318,8 @@ sponsors:
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/861044?u=5abfca5588f3e906b31583d7ee62f6de4b68aa24&v=4
|
||||
url: https://github.com/browniebroke
|
||||
- login: janfilips
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/870699?u=50de77b93d3a0b06887e672d4e8c7b9d643085aa&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/870699?u=96df18ad355e58b9397accc55f4eeb7a86e959b0&v=4
|
||||
url: https://github.com/janfilips
|
||||
- login: allen0125
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1448456?u=dc2ad819497eef494b88688a1796e0adb87e7cae&v=4
|
||||
url: https://github.com/allen0125
|
||||
- login: WillHogan
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1661551?u=7036c064cf29781470573865264ec8e60b6b809f&v=4
|
||||
url: https://github.com/WillHogan
|
||||
@@ -392,17 +329,20 @@ sponsors:
|
||||
- login: cbonoz
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2351087?u=fd3e8030b2cc9fbfbb54a65e9890c548a016f58b&v=4
|
||||
url: https://github.com/cbonoz
|
||||
- login: paul121
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3116995?u=6e2d8691cc345e63ee02e4eb4d7cef82b1fcbedc&v=4
|
||||
url: https://github.com/paul121
|
||||
- login: Patechoc
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2376641?u=23b49e9eda04f078cb74fa3f93593aa6a57bb138&v=4
|
||||
url: https://github.com/Patechoc
|
||||
- login: larsvik
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3442226?v=4
|
||||
url: https://github.com/larsvik
|
||||
- login: anthonycorletti
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3477132?v=4
|
||||
url: https://github.com/anthonycorletti
|
||||
- login: jonathanhle
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/3851599?u=76b9c5d2fecd6c3a16e7645231878c4507380d4d&v=4
|
||||
url: https://github.com/jonathanhle
|
||||
- login: nikeee
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4068864?u=63f8eee593f25138e0f1032ef442e9ad24907d4c&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4068864?u=bbe73151f2b409c120160d032dc9aa6875ef0c4b&v=4
|
||||
url: https://github.com/nikeee
|
||||
- login: Alisa-lisa
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4137964?u=e7e393504f554f4ff15863a1e01a5746863ef9ce&v=4
|
||||
@@ -410,6 +350,12 @@ sponsors:
|
||||
- login: danielunderwood
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4472301?v=4
|
||||
url: https://github.com/danielunderwood
|
||||
- login: yuawn
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5111198?u=5315576f3fe1a70fd2d0f02181588f4eea5d353d&v=4
|
||||
url: https://github.com/yuawn
|
||||
- login: sdevkota
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5250987?u=4ed9a120c89805a8aefda1cbdc0cf6512e64d1b4&v=4
|
||||
url: https://github.com/sdevkota
|
||||
- login: unredundant
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5607577?u=1ffbf39f5bb8736b75c0d235707d6e8f803725c5&v=4
|
||||
url: https://github.com/unredundant
|
||||
@@ -419,11 +365,11 @@ sponsors:
|
||||
- login: KentShikama
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6329898?u=8b236810db9b96333230430837e1f021f9246da1&v=4
|
||||
url: https://github.com/KentShikama
|
||||
- login: holec
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6438041?u=f5af71ec85b3a9d7b8139cb5af0512b02fa9ab1e&v=4
|
||||
url: https://github.com/holec
|
||||
- login: katnoria
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7674948?u=09767eb13e07e09496c5fee4e5ce21d9eac34a56&v=4
|
||||
url: https://github.com/katnoria
|
||||
- login: mattwelke
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7719209?v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7719209?u=80f02a799323b1472b389b836d95957c93a6d856&v=4
|
||||
url: https://github.com/mattwelke
|
||||
- login: hcristea
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7814406?u=61d7a4fcf846983a4606788eac25e1c6c1209ba8&v=4
|
||||
@@ -431,6 +377,9 @@ sponsors:
|
||||
- login: moonape1226
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8532038?u=d9f8b855a429fff9397c3833c2ff83849ebf989d&v=4
|
||||
url: https://github.com/moonape1226
|
||||
- login: albertkun
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/8574425?u=aad2a9674273c9275fe414d99269b7418d144089&v=4
|
||||
url: https://github.com/albertkun
|
||||
- login: xncbf
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9462045?u=866a1311e4bd3ec5ae84185c4fcc99f397c883d7&v=4
|
||||
url: https://github.com/xncbf
|
||||
@@ -440,6 +389,9 @@ sponsors:
|
||||
- login: hard-coders
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
|
||||
url: https://github.com/hard-coders
|
||||
- login: supdann
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9986994?u=9671810f4ae9504c063227fee34fd47567ff6954&v=4
|
||||
url: https://github.com/supdann
|
||||
- login: satwikkansal
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10217535?u=b12d6ef74ea297de9e46da6933b1a5b7ba9e6a61&v=4
|
||||
url: https://github.com/satwikkansal
|
||||
@@ -456,38 +408,32 @@ sponsors:
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/13181797?u=0ef2dfbf7fc9a9726d45c21d32b5d1038a174870&v=4
|
||||
url: https://github.com/giuliano-oliveira
|
||||
- login: TheR1D
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16740832?u=b2923ac17fe6e2a7c9ea14800351ddb92f79b100&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16740832?u=b0dfdbdb27b79729430c71c6128962f77b7b53f7&v=4
|
||||
url: https://github.com/TheR1D
|
||||
- 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: paulowiz
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/18649504?u=d8a6ac40321f2bded0eba78b637751c7f86c6823&v=4
|
||||
url: https://github.com/paulowiz
|
||||
- login: ghandic
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/23500353?u=e2e1d736f924d9be81e8bfc565b6d8836ba99773&v=4
|
||||
url: https://github.com/ghandic
|
||||
- login: pers0n4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/24864600?u=f211a13a7b572cbbd7779b9c8d8cb428cc7ba07e&v=4
|
||||
url: https://github.com/pers0n4
|
||||
- login: SebTota
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/25122511?v=4
|
||||
url: https://github.com/SebTota
|
||||
- login: kadekillary
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/25046261?u=e185e58080090f9e678192cd214a14b14a2b232b&v=4
|
||||
url: https://github.com/kadekillary
|
||||
- login: hoenie-ams
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/25708487?u=cda07434f0509ac728d9edf5e681117c0f6b818b&v=4
|
||||
url: https://github.com/hoenie-ams
|
||||
- login: joerambo
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/26282974?v=4
|
||||
url: https://github.com/joerambo
|
||||
- login: rlnchow
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/28018479?u=a93ca9cf1422b9ece155784a72d5f2fdbce7adff&v=4
|
||||
url: https://github.com/rlnchow
|
||||
- login: mertguvencli
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/29762151?u=16a906d90df96c8cff9ea131a575c4bc171b1523&v=4
|
||||
url: https://github.com/mertguvencli
|
||||
- login: ruizdiazever
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/29817086?u=2df54af55663d246e3a4dc8273711c37f1adb117&v=4
|
||||
url: https://github.com/ruizdiazever
|
||||
- login: HosamAlmoghraby
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/32025281?u=aa1b09feabccbf9dc506b81c71155f32d126cefa&v=4
|
||||
url: https://github.com/HosamAlmoghraby
|
||||
@@ -495,53 +441,56 @@ sponsors:
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/33275230?u=eb223cad27017bb1e936ee9b429b450d092d0236&v=4
|
||||
url: https://github.com/engineerjoe440
|
||||
- login: bnkc
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/34930566?u=76cdc0a8b4e88c7d3e58dccb4b2670839e1247b4&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/34930566?u=9fbf76b9bf7786275e2900efa51d1394bcf1f06a&v=4
|
||||
url: https://github.com/bnkc
|
||||
- login: declon
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/36180226?v=4
|
||||
url: https://github.com/declon
|
||||
- login: alvarobartt
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/36760800?u=9b38695807eb981d452989699ff72ec2d8f6508e&v=4
|
||||
url: https://github.com/alvarobartt
|
||||
- login: d-e-h-i-o
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/36816716?v=4
|
||||
url: https://github.com/d-e-h-i-o
|
||||
- login: ww-daniel-mora
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/38921751?u=ae14bc1e40f2dd5a9c5741fc0b0dffbd416a5fa9&v=4
|
||||
url: https://github.com/ww-daniel-mora
|
||||
- login: rwxd
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/40308458?u=cd04a39e3655923be4f25c2ba8a5a07b3da3230a&v=4
|
||||
url: https://github.com/rwxd
|
||||
- login: miraedbswo
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/36796047?u=9e7a5b3e558edc61d35d0f9dfac37541bae7f56d&v=4
|
||||
url: https://github.com/miraedbswo
|
||||
- login: kristiangronberg
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/42678548?v=4
|
||||
url: https://github.com/kristiangronberg
|
||||
- login: arrrrrmin
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/43553423?u=5265858add14a6822bd145f7547323cf078563e6&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/43553423?u=36a3880a6eb29309c19e6cadbb173bafbe91deb1&v=4
|
||||
url: https://github.com/arrrrrmin
|
||||
- login: ArtyomVancyan
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/44609997?v=4
|
||||
url: https://github.com/ArtyomVancyan
|
||||
- login: hgalytoby
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/50397689?u=f4888c2c54929bd86eed0d3971d09fcb306e5088&v=4
|
||||
url: https://github.com/hgalytoby
|
||||
- login: data-djinn
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/56449985?u=42146e140806908d49bd59ccc96f222abf587886&v=4
|
||||
url: https://github.com/data-djinn
|
||||
- login: eladgunders
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/52347338?u=83d454817cf991a035c8827d46ade050c813e2d6&v=4
|
||||
url: https://github.com/eladgunders
|
||||
- login: conservative-dude
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/55538308?u=f250c44942ea6e73a6bd90739b381c470c192c11&v=4
|
||||
url: https://github.com/conservative-dude
|
||||
- login: leo-jp-edwards
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/58213433?u=2c128e8b0794b7a66211cd7d8ebe05db20b7e9c0&v=4
|
||||
url: https://github.com/leo-jp-edwards
|
||||
- login: apar-tiwari
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/61064197?v=4
|
||||
url: https://github.com/apar-tiwari
|
||||
- login: Vyvy-vi
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/62864373?u=1a9b0b28779abc2bc9b62cb4d2e44d453973c9c3&v=4
|
||||
url: https://github.com/Vyvy-vi
|
||||
- login: tamtam-fitness
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/62091034?u=8da19a6bd3d02f5d6ba30c7247d5b46c98dd1403&v=4
|
||||
url: https://github.com/tamtam-fitness
|
||||
- login: 0417taehyun
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/63915557?u=47debaa860fd52c9b98c97ef357ddcec3b3fb399&v=4
|
||||
url: https://github.com/0417taehyun
|
||||
- login: realabja
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/66185192?u=001e2dd9297784f4218997981b4e6fa8357bb70b&v=4
|
||||
url: https://github.com/realabja
|
||||
- login: garydsong
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/105745865?u=03cc1aa9c978be0020e5a1ce1ecca323dd6c8d65&v=4
|
||||
url: https://github.com/garydsong
|
||||
- - login: Leon0824
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1922026?v=4
|
||||
url: https://github.com/Leon0824
|
||||
- - login: ssbarnea
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/102495?u=b4bf6818deefe59952ac22fec6ed8c76de1b8f7c&v=4
|
||||
url: https://github.com/ssbarnea
|
||||
- login: sadikkuzu
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/23168063?u=d179c06bb9f65c4167fcab118526819f8e0dac17&v=4
|
||||
url: https://github.com/sadikkuzu
|
||||
- login: ruizdiazever
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/29817086?u=2df54af55663d246e3a4dc8273711c37f1adb117&v=4
|
||||
url: https://github.com/ruizdiazever
|
||||
- login: danburonline
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/34251194?u=2cad4388c1544e539ecb732d656e42fb07b4ff2d&v=4
|
||||
url: https://github.com/danburonline
|
||||
- login: rwxd
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/40308458?u=cd04a39e3655923be4f25c2ba8a5a07b3da3230a&v=4
|
||||
url: https://github.com/rwxd
|
||||
- login: xNykram
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/55030025?u=2c1ba313fd79d29273b5ff7c9c5cf4edfb271b29&v=4
|
||||
url: https://github.com/xNykram
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
maintainers:
|
||||
- login: tiangolo
|
||||
answers: 1827
|
||||
prs: 384
|
||||
answers: 1839
|
||||
prs: 398
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1326112?u=740f11212a731f56798f558ceddb0bd07642afa7&v=4
|
||||
url: https://github.com/tiangolo
|
||||
experts:
|
||||
- login: Kludex
|
||||
count: 376
|
||||
count: 410
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
|
||||
url: https://github.com/Kludex
|
||||
- login: dmontagu
|
||||
@@ -22,69 +22,73 @@ experts:
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/62724709?u=bba5af018423a2858d49309bed2a899bb5c34ac5&v=4
|
||||
url: https://github.com/ycd
|
||||
- login: JarroVGIT
|
||||
count: 192
|
||||
count: 193
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/13659033?u=e8bea32d07a5ef72f7dde3b2079ceb714923ca05&v=4
|
||||
url: https://github.com/JarroVGIT
|
||||
- login: euri10
|
||||
count: 151
|
||||
count: 152
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1104190?u=321a2e953e6645a7d09b732786c7a8061e0f8a8b&v=4
|
||||
url: https://github.com/euri10
|
||||
- login: phy25
|
||||
count: 126
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/331403?v=4
|
||||
url: https://github.com/phy25
|
||||
- login: iudeen
|
||||
count: 116
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4
|
||||
url: https://github.com/iudeen
|
||||
- login: jgould22
|
||||
count: 101
|
||||
count: 124
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
|
||||
url: https://github.com/jgould22
|
||||
- login: iudeen
|
||||
count: 118
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10519440?u=2843b3303282bff8b212dcd4d9d6689452e4470c&v=4
|
||||
url: https://github.com/iudeen
|
||||
- login: raphaelauv
|
||||
count: 83
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
|
||||
url: https://github.com/raphaelauv
|
||||
- login: ArcLightSlavik
|
||||
count: 71
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=b0f2c37142f4b762e41ad65dc49581813422bd71&v=4
|
||||
url: https://github.com/ArcLightSlavik
|
||||
- login: ghandic
|
||||
count: 71
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/23500353?u=e2e1d736f924d9be81e8bfc565b6d8836ba99773&v=4
|
||||
url: https://github.com/ghandic
|
||||
- login: ArcLightSlavik
|
||||
count: 71
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=b0f2c37142f4b762e41ad65dc49581813422bd71&v=4
|
||||
url: https://github.com/ArcLightSlavik
|
||||
- login: falkben
|
||||
count: 57
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/653031?u=0c8d8f33d87f1aa1a6488d3f02105e9abc838105&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/653031?u=ad9838e089058c9e5a0bab94c0eec7cc181e0cd0&v=4
|
||||
url: https://github.com/falkben
|
||||
- login: sm-Fifteen
|
||||
count: 49
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/516999?u=437c0c5038558c67e887ccd863c1ba0f846c03da&v=4
|
||||
url: https://github.com/sm-Fifteen
|
||||
- login: Dustyposa
|
||||
- login: yinziyan1206
|
||||
count: 45
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4
|
||||
url: https://github.com/Dustyposa
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/37829370?u=da44ca53aefd5c23f346fab8e9fd2e108294c179&v=4
|
||||
url: https://github.com/yinziyan1206
|
||||
- login: insomnes
|
||||
count: 45
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16958893?u=f8be7088d5076d963984a21f95f44e559192d912&v=4
|
||||
url: https://github.com/insomnes
|
||||
- login: acidjunk
|
||||
count: 45
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
|
||||
url: https://github.com/acidjunk
|
||||
- login: Dustyposa
|
||||
count: 45
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/27180793?u=5cf2877f50b3eb2bc55086089a78a36f07042889&v=4
|
||||
url: https://github.com/Dustyposa
|
||||
- login: adriangb
|
||||
count: 43
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1755071?u=1e2c2c9b39f5c9b780fb933d8995cf08ec235a47&v=4
|
||||
url: https://github.com/adriangb
|
||||
- login: frankie567
|
||||
count: 43
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1144727?u=85c025e3fcc7bd79a5665c63ee87cdf8aae13374&v=4
|
||||
url: https://github.com/frankie567
|
||||
- login: acidjunk
|
||||
count: 43
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/685002?u=b5094ab4527fc84b006c0ac9ff54367bdebb2267&v=4
|
||||
url: https://github.com/acidjunk
|
||||
- login: odiseo0
|
||||
count: 42
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/87550035?u=16f9255804161c6ff3c8b7ef69848f0126bcd405&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/87550035?u=2da05dab6cc8e1ade557801634760a56e4101796&v=4
|
||||
url: https://github.com/odiseo0
|
||||
- login: adriangb
|
||||
count: 40
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1755071?u=1e2c2c9b39f5c9b780fb933d8995cf08ec235a47&v=4
|
||||
url: https://github.com/adriangb
|
||||
- login: includeamin
|
||||
count: 40
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11836741?u=8bd5ef7e62fe6a82055e33c4c0e0a7879ff8cfb6&v=4
|
||||
@@ -97,12 +101,8 @@ experts:
|
||||
count: 35
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31960541?u=47f4829c77f4962ab437ffb7995951e41eeebe9b&v=4
|
||||
url: https://github.com/krishnardt
|
||||
- login: yinziyan1206
|
||||
count: 34
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/37829370?u=da44ca53aefd5c23f346fab8e9fd2e108294c179&v=4
|
||||
url: https://github.com/yinziyan1206
|
||||
- login: chbndrhnns
|
||||
count: 34
|
||||
count: 35
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7534547?v=4
|
||||
url: https://github.com/chbndrhnns
|
||||
- login: panla
|
||||
@@ -125,10 +125,10 @@ experts:
|
||||
count: 23
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9435877?u=719327b7d2c4c62212456d771bfa7c6b8dbb9eac&v=4
|
||||
url: https://github.com/SirTelemak
|
||||
- login: caeser1996
|
||||
count: 21
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16540232?u=05d2beb8e034d584d0a374b99d8826327bd7f614&v=4
|
||||
url: https://github.com/caeser1996
|
||||
- login: acnebs
|
||||
count: 22
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9054108?u=c27e50269f1ef8ea950cc6f0268c8ec5cebbe9c9&v=4
|
||||
url: https://github.com/acnebs
|
||||
- login: rafsaf
|
||||
count: 21
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/51059348?u=f8f0d6d6e90fac39fa786228158ba7f013c74271&v=4
|
||||
@@ -137,34 +137,38 @@ experts:
|
||||
count: 20
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/22559461?u=a9cc3238217e21dc8796a1a500f01b722adb082c&v=4
|
||||
url: https://github.com/nsidnev
|
||||
- login: acnebs
|
||||
count: 20
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9054108?u=c27e50269f1ef8ea950cc6f0268c8ec5cebbe9c9&v=4
|
||||
url: https://github.com/acnebs
|
||||
- login: chris-allnutt
|
||||
count: 20
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/565544?v=4
|
||||
url: https://github.com/chris-allnutt
|
||||
- login: retnikt
|
||||
count: 18
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/24581770?v=4
|
||||
url: https://github.com/retnikt
|
||||
- login: zoliknemet
|
||||
count: 18
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/22326718?u=31ba446ac290e23e56eea8e4f0c558aaf0b40779&v=4
|
||||
url: https://github.com/zoliknemet
|
||||
- login: nkhitrov
|
||||
count: 17
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/28262306?u=66ee21316275ef356081c2efc4ed7a4572e690dc&v=4
|
||||
url: https://github.com/nkhitrov
|
||||
- login: harunyasar
|
||||
count: 17
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1765494?u=5b1ab7c582db4b4016fa31affe977d10af108ad4&v=4
|
||||
url: https://github.com/harunyasar
|
||||
- login: retnikt
|
||||
count: 18
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/24581770?v=4
|
||||
url: https://github.com/retnikt
|
||||
- login: Hultner
|
||||
count: 17
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2669034?u=115e53df959309898ad8dc9443fbb35fee71df07&v=4
|
||||
url: https://github.com/Hultner
|
||||
- login: n8sty
|
||||
count: 17
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2964996?v=4
|
||||
url: https://github.com/n8sty
|
||||
- login: harunyasar
|
||||
count: 17
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1765494?u=5b1ab7c582db4b4016fa31affe977d10af108ad4&v=4
|
||||
url: https://github.com/harunyasar
|
||||
- login: nkhitrov
|
||||
count: 17
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/28262306?u=66ee21316275ef356081c2efc4ed7a4572e690dc&v=4
|
||||
url: https://github.com/nkhitrov
|
||||
- login: caeser1996
|
||||
count: 17
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16540232?u=05d2beb8e034d584d0a374b99d8826327bd7f614&v=4
|
||||
url: https://github.com/caeser1996
|
||||
- login: jonatasoli
|
||||
count: 16
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/26334101?u=071c062d2861d3dd127f6b4a5258cd8ef55d4c50&v=4
|
||||
@@ -173,10 +177,6 @@ experts:
|
||||
count: 16
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/41964673?u=9f2174f9d61c15c6e3a4c9e3aeee66f711ce311f&v=4
|
||||
url: https://github.com/dstlny
|
||||
- login: jorgerpo
|
||||
count: 15
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/12537771?u=7444d20019198e34911082780cc7ad73f2b97cb3&v=4
|
||||
url: https://github.com/jorgerpo
|
||||
- login: ghost
|
||||
count: 15
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10137?u=b1951d34a583cf12ec0d3b0781ba19be97726318&v=4
|
||||
@@ -185,55 +185,43 @@ experts:
|
||||
count: 15
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/33907262?v=4
|
||||
url: https://github.com/simondale00
|
||||
- login: jorgerpo
|
||||
count: 15
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/12537771?u=7444d20019198e34911082780cc7ad73f2b97cb3&v=4
|
||||
url: https://github.com/jorgerpo
|
||||
- login: ebottos94
|
||||
count: 14
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/100039558?u=e2c672da5a7977fd24d87ce6ab35f8bf5b1ed9fa&v=4
|
||||
url: https://github.com/ebottos94
|
||||
- login: hellocoldworld
|
||||
count: 14
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/47581948?u=3d2186796434c507a6cb6de35189ab0ad27c356f&v=4
|
||||
url: https://github.com/hellocoldworld
|
||||
- login: waynerv
|
||||
count: 14
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/39515546?u=ec35139777597cdbbbddda29bf8b9d4396b429a9&v=4
|
||||
url: https://github.com/waynerv
|
||||
- login: mbroton
|
||||
count: 13
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/50829834?u=a48610bf1bffaa9c75d03228926e2eb08a2e24ee&v=4
|
||||
url: https://github.com/mbroton
|
||||
last_month_active:
|
||||
- login: mr-st0rm
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/48455163?u=6b83550e4e70bea57cd2fdb41e717aeab7f64a91&v=4
|
||||
url: https://github.com/mr-st0rm
|
||||
- login: caeser1996
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16540232?u=05d2beb8e034d584d0a374b99d8826327bd7f614&v=4
|
||||
url: https://github.com/caeser1996
|
||||
- login: ebottos94
|
||||
count: 6
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/100039558?u=e2c672da5a7977fd24d87ce6ab35f8bf5b1ed9fa&v=4
|
||||
url: https://github.com/ebottos94
|
||||
- login: jgould22
|
||||
count: 6
|
||||
count: 13
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4335847?u=ed77f67e0bb069084639b24d812dbb2a2b1dc554&v=4
|
||||
url: https://github.com/jgould22
|
||||
- login: Kludex
|
||||
count: 5
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
|
||||
url: https://github.com/Kludex
|
||||
- login: clemens-tolboom
|
||||
- login: abhint
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/25699289?u=5b9f9f6192c83ca86a411eafd4be46d9e5828585&v=4
|
||||
url: https://github.com/abhint
|
||||
- login: chrisK824
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/371014?v=4
|
||||
url: https://github.com/clemens-tolboom
|
||||
- login: williamjamir
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/79946379?u=03d85b22d696a58a9603e55fbbbe2de6b0f4face&v=4
|
||||
url: https://github.com/chrisK824
|
||||
- login: djimontyp
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5083518?u=b76ca8e08b906a86fa195fb817dd94e8d9d3d8f6&v=4
|
||||
url: https://github.com/williamjamir
|
||||
- login: nymous
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/53098395?u=583bade70950b277c322d35f1be2b75c7b0f189c&v=4
|
||||
url: https://github.com/djimontyp
|
||||
- login: JavierSanchezCastro
|
||||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4216559?u=360a36fb602cded27273cbfc0afc296eece90662&v=4
|
||||
url: https://github.com/nymous
|
||||
- login: frankie567
|
||||
count: 3
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1144727?u=85c025e3fcc7bd79a5665c63ee87cdf8aae13374&v=4
|
||||
url: https://github.com/frankie567
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/72013291?u=ae5679e6bd971d9d98cd5e76e8683f83642ba950&v=4
|
||||
url: https://github.com/JavierSanchezCastro
|
||||
top_contributors:
|
||||
- login: waynerv
|
||||
count: 25
|
||||
@@ -263,6 +251,10 @@ top_contributors:
|
||||
count: 12
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11489395?u=4adb6986bf3debfc2b8216ae701f2bd47d73da7d&v=4
|
||||
url: https://github.com/mariacamilagl
|
||||
- login: Xewus
|
||||
count: 12
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/85196001?u=f8e2dc7e5104f109cef944af79050ea8d1b8f914&v=4
|
||||
url: https://github.com/Xewus
|
||||
- login: Smlep
|
||||
count: 10
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16785985?v=4
|
||||
@@ -271,6 +263,10 @@ top_contributors:
|
||||
count: 8
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/22691749?u=4795b880e13ca33a73e52fc0ef7dc9c60c8fce47&v=4
|
||||
url: https://github.com/Serrones
|
||||
- login: rjNemo
|
||||
count: 8
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/56785022?u=d5c3a02567c8649e146fcfc51b6060ccaf8adef8&v=4
|
||||
url: https://github.com/rjNemo
|
||||
- login: RunningIkkyu
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31848542?u=494ecc298e3f26197495bb357ad0f57cfd5f7a32&v=4
|
||||
@@ -279,10 +275,6 @@ top_contributors:
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
|
||||
url: https://github.com/hard-coders
|
||||
- login: rjNemo
|
||||
count: 7
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/56785022?u=d5c3a02567c8649e146fcfc51b6060ccaf8adef8&v=4
|
||||
url: https://github.com/rjNemo
|
||||
- login: batlopes
|
||||
count: 6
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/33462923?u=0fb3d7acb316764616f11e4947faf080e49ad8d9&v=4
|
||||
@@ -291,6 +283,10 @@ top_contributors:
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/365303?u=07ca03c5ee811eb0920e633cc3c3db73dbec1aa5&v=4
|
||||
url: https://github.com/wshayes
|
||||
- login: samuelcolvin
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4039449?u=807390ba9cfe23906c3bf8a0d56aaca3cf2bfa0d&v=4
|
||||
url: https://github.com/samuelcolvin
|
||||
- login: SwftAlpc
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/52768429?u=6a3aa15277406520ad37f6236e89466ed44bc5b8&v=4
|
||||
@@ -307,18 +303,10 @@ top_contributors:
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/79563565?u=eee6bfe9224c71193025ab7477f4f96ceaa05c62&v=4
|
||||
url: https://github.com/NinaHwang
|
||||
- login: Xewus
|
||||
count: 5
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/85196001?u=f8e2dc7e5104f109cef944af79050ea8d1b8f914&v=4
|
||||
url: https://github.com/Xewus
|
||||
- login: jekirl
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2546697?u=a027452387d85bd4a14834e19d716c99255fb3b7&v=4
|
||||
url: https://github.com/jekirl
|
||||
- login: samuelcolvin
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4039449?u=807390ba9cfe23906c3bf8a0d56aaca3cf2bfa0d&v=4
|
||||
url: https://github.com/samuelcolvin
|
||||
- login: jfunez
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/805749?v=4
|
||||
@@ -339,9 +327,13 @@ top_contributors:
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/61513630?u=320e43fe4dc7bc6efc64e9b8f325f8075634fd20&v=4
|
||||
url: https://github.com/lsglucas
|
||||
- login: axel584
|
||||
count: 4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1334088?u=9667041f5b15dc002b6f9665fda8c0412933ac04&v=4
|
||||
url: https://github.com/axel584
|
||||
top_reviewers:
|
||||
- login: Kludex
|
||||
count: 111
|
||||
count: 117
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/7353520?u=62adc405ef418f4b6c8caa93d3eb8ab107bc4927&v=4
|
||||
url: https://github.com/Kludex
|
||||
- login: BilalAlpaslan
|
||||
@@ -349,8 +341,8 @@ top_reviewers:
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/47563997?u=63ed66e304fe8d765762c70587d61d9196e5c82d&v=4
|
||||
url: https://github.com/BilalAlpaslan
|
||||
- login: yezz123
|
||||
count: 71
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/52716203?u=636b4f79645176df4527dd45c12d5dbb5a4193cf&v=4
|
||||
count: 74
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/52716203?u=d7062cbc6eb7671d5dc9cc0e32a24ae335e0f225&v=4
|
||||
url: https://github.com/yezz123
|
||||
- login: tokusumi
|
||||
count: 51
|
||||
@@ -384,6 +376,10 @@ top_reviewers:
|
||||
count: 33
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1024932?u=b2ea249c6b41ddf98679c8d110d0f67d4a3ebf93&v=4
|
||||
url: https://github.com/AdrianDeAnda
|
||||
- login: Xewus
|
||||
count: 32
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/85196001?u=f8e2dc7e5104f109cef944af79050ea8d1b8f914&v=4
|
||||
url: https://github.com/Xewus
|
||||
- login: ArcLightSlavik
|
||||
count: 31
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31127044?u=b0f2c37142f4b762e41ad65dc49581813422bd71&v=4
|
||||
@@ -400,30 +396,34 @@ top_reviewers:
|
||||
count: 26
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/61513630?u=320e43fe4dc7bc6efc64e9b8f325f8075634fd20&v=4
|
||||
url: https://github.com/lsglucas
|
||||
- login: Ryandaydev
|
||||
count: 24
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4292423?u=809f3d1074d04bbc28012a7f17f06ea56f5bd71a&v=4
|
||||
url: https://github.com/Ryandaydev
|
||||
- login: dmontagu
|
||||
count: 23
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/35119617?u=58ed2a45798a4339700e2f62b2e12e6e54bf0396&v=4
|
||||
url: https://github.com/dmontagu
|
||||
- login: LorhanSohaky
|
||||
count: 22
|
||||
count: 23
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16273730?u=095b66f243a2cd6a0aadba9a095009f8aaf18393&v=4
|
||||
url: https://github.com/LorhanSohaky
|
||||
- login: rjNemo
|
||||
count: 20
|
||||
count: 21
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/56785022?u=d5c3a02567c8649e146fcfc51b6060ccaf8adef8&v=4
|
||||
url: https://github.com/rjNemo
|
||||
- login: hard-coders
|
||||
count: 20
|
||||
count: 21
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/9651103?u=95db33927bbff1ed1c07efddeb97ac2ff33068ed&v=4
|
||||
url: https://github.com/hard-coders
|
||||
- login: odiseo0
|
||||
count: 20
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/87550035?u=2da05dab6cc8e1ade557801634760a56e4101796&v=4
|
||||
url: https://github.com/odiseo0
|
||||
- login: 0417taehyun
|
||||
count: 19
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/63915557?u=47debaa860fd52c9b98c97ef357ddcec3b3fb399&v=4
|
||||
url: https://github.com/0417taehyun
|
||||
- login: odiseo0
|
||||
count: 19
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/87550035?u=16f9255804161c6ff3c8b7ef69848f0126bcd405&v=4
|
||||
url: https://github.com/odiseo0
|
||||
- login: Smlep
|
||||
count: 17
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/16785985?v=4
|
||||
@@ -452,34 +452,38 @@ top_reviewers:
|
||||
count: 15
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/63476957?u=6c86e59b48e0394d4db230f37fc9ad4d7e2c27c7&v=4
|
||||
url: https://github.com/delhi09
|
||||
- login: Ryandaydev
|
||||
count: 15
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/4292423?u=809f3d1074d04bbc28012a7f17f06ea56f5bd71a&v=4
|
||||
url: https://github.com/Ryandaydev
|
||||
- login: Xewus
|
||||
count: 14
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/85196001?u=f8e2dc7e5104f109cef944af79050ea8d1b8f914&v=4
|
||||
url: https://github.com/Xewus
|
||||
- login: sh0nk
|
||||
count: 13
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/6478810?u=af15d724875cec682ed8088a86d36b2798f981c0&v=4
|
||||
url: https://github.com/sh0nk
|
||||
- login: peidrao
|
||||
count: 13
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/32584628?u=5401640e0b961cc199dee39ec79e162c7833cd6b&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/32584628?u=5b94b548ef0002ef3219d7c07ac0fac17c6201a2&v=4
|
||||
url: https://github.com/peidrao
|
||||
- login: r0b2g1t
|
||||
count: 13
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5357541?u=6428442d875d5d71aaa1bb38bb11c4be1a526bc2&v=4
|
||||
url: https://github.com/r0b2g1t
|
||||
- login: RunningIkkyu
|
||||
count: 12
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/31848542?u=494ecc298e3f26197495bb357ad0f57cfd5f7a32&v=4
|
||||
url: https://github.com/RunningIkkyu
|
||||
- login: axel584
|
||||
count: 12
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1334088?u=9667041f5b15dc002b6f9665fda8c0412933ac04&v=4
|
||||
url: https://github.com/axel584
|
||||
- login: solomein-sv
|
||||
count: 11
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/46193920?u=46acfb4aeefb1d7b9fdc5a8cbd9eb8744683c47a&v=4
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/46193920?u=789927ee09cfabd752d3bd554fa6baf4850d2777&v=4
|
||||
url: https://github.com/solomein-sv
|
||||
- login: mariacamilagl
|
||||
count: 10
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/11489395?u=4adb6986bf3debfc2b8216ae701f2bd47d73da7d&v=4
|
||||
url: https://github.com/mariacamilagl
|
||||
- login: raphaelauv
|
||||
count: 10
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
|
||||
url: https://github.com/raphaelauv
|
||||
- login: Attsun1031
|
||||
count: 10
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1175560?v=4
|
||||
@@ -492,10 +496,10 @@ top_reviewers:
|
||||
count: 10
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/43503750?u=f440bc9062afb3c43b9b9c6cdfdcfe31d58699ef&v=4
|
||||
url: https://github.com/ComicShrimp
|
||||
- login: r0b2g1t
|
||||
- login: Alexandrhub
|
||||
count: 10
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5357541?u=6428442d875d5d71aaa1bb38bb11c4be1a526bc2&v=4
|
||||
url: https://github.com/r0b2g1t
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/119126536?u=9fc0d48f3307817bafecc5861eb2168401a6cb04&v=4
|
||||
url: https://github.com/Alexandrhub
|
||||
- login: izaguerreiro
|
||||
count: 9
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/2241504?v=4
|
||||
@@ -516,23 +520,11 @@ top_reviewers:
|
||||
count: 9
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/69092910?u=4ac58eab99bd37d663f3d23551df96d4fbdbf760&v=4
|
||||
url: https://github.com/bezaca
|
||||
- login: dimaqq
|
||||
- login: oandersonmagalhaes
|
||||
count: 9
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/662249?v=4
|
||||
url: https://github.com/dimaqq
|
||||
- login: raphaelauv
|
||||
count: 8
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/10202690?u=e6f86f5c0c3026a15d6b51792fa3e532b12f1371&v=4
|
||||
url: https://github.com/raphaelauv
|
||||
- login: axel584
|
||||
count: 8
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/1334088?v=4
|
||||
url: https://github.com/axel584
|
||||
- login: blt232018
|
||||
count: 8
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/43393471?u=172b0e0391db1aa6c1706498d6dfcb003c8a4857&v=4
|
||||
url: https://github.com/blt232018
|
||||
- login: rogerbrinkmann
|
||||
count: 8
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/5690226?v=4
|
||||
url: https://github.com/rogerbrinkmann
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/83456692?v=4
|
||||
url: https://github.com/oandersonmagalhaes
|
||||
- login: NinaHwang
|
||||
count: 9
|
||||
avatarUrl: https://avatars.githubusercontent.com/u/79563565?u=eee6bfe9224c71193025ab7477f4f96ceaa05c62&v=4
|
||||
url: https://github.com/NinaHwang
|
||||
|
||||
@@ -2,13 +2,13 @@ gold:
|
||||
- url: https://cryptapi.io/
|
||||
title: "CryptAPI: Your easy to use, secure and privacy oriented payment gateway."
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/cryptapi.svg
|
||||
- url: https://platform.sh/try-it-now/?utm_source=fastapi-signup&utm_medium=banner&utm_campaign=FastAPI-signup-June-2023
|
||||
title: "Build, run and scale your apps on a modern, reliable, and secure PaaS."
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/platform-sh.png
|
||||
silver:
|
||||
- url: https://www.deta.sh/?ref=fastapi
|
||||
title: The launchpad for all your (team's) ideas
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/deta.svg
|
||||
- url: https://www.investsuite.com/jobs
|
||||
title: Wealthtech jobs with FastAPI
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/investsuite.svg
|
||||
- url: https://training.talkpython.fm/fastapi-courses
|
||||
title: FastAPI video courses on demand from people you trust
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/talkpython.png
|
||||
@@ -31,3 +31,6 @@ bronze:
|
||||
- url: https://www.exoflare.com/open-source/?utm_source=FastAPI&utm_campaign=open_source
|
||||
title: Biosecurity risk assessments made easy.
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/exoflare.png
|
||||
- url: https://www.flint.sh
|
||||
title: IT expertise, consulting and development by passionate people
|
||||
img: https://fastapi.tiangolo.com/img/sponsors/flint.png
|
||||
|
||||
@@ -15,3 +15,5 @@ logins:
|
||||
- svix
|
||||
- armand-sauzay
|
||||
- databento-bot
|
||||
- nanram22
|
||||
- Flint-company
|
||||
|
||||
@@ -44,7 +44,7 @@ So the new file structure looks like:
|
||||
|
||||
First, we create a new database session with the new database.
|
||||
|
||||
For the tests we'll use a file `test.db` instead of `sql_app.db`.
|
||||
We'll use an in-memory database that persists during the tests instead of the local file `sql_app.db`.
|
||||
|
||||
But the rest of the session code is more or less the same, we just copy it.
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ Then wrap the WSGI (e.g. Flask) app with the middleware.
|
||||
|
||||
And then mount that under a path.
|
||||
|
||||
```Python hl_lines="2-3 22"
|
||||
```Python hl_lines="2-3 23"
|
||||
{!../../../docs_src/wsgi/tutorial001.py!}
|
||||
```
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ After activating the environment as described above:
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install -e ."[dev,doc,test]"
|
||||
$ pip install -r requirements.txt
|
||||
|
||||
---> 100%
|
||||
```
|
||||
@@ -121,10 +121,15 @@ It will install all the dependencies and your local FastAPI in your local enviro
|
||||
|
||||
If you create a Python file that imports and uses FastAPI, and run it with the Python from your local environment, it will use your local FastAPI source code.
|
||||
|
||||
And if you update that local FastAPI source code, as it is installed with `-e`, when you run that Python file again, it will use the fresh version of FastAPI you just edited.
|
||||
And if you update that local FastAPI source code when you run that Python file again, it will use the fresh version of FastAPI you just edited.
|
||||
|
||||
That way, you don't have to "install" your local version to be able to test every change.
|
||||
|
||||
!!! note "Technical Details"
|
||||
This only happens when you install using this included `requiements.txt` instead of installing `pip install fastapi` directly.
|
||||
|
||||
That is because inside of the `requirements.txt` file, the local version of FastAPI is marked to be installed in "editable" mode, with the `-e` option.
|
||||
|
||||
### Format
|
||||
|
||||
There is a script that you can run that will format and clean all your code:
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
# Deploy FastAPI on Deta
|
||||
# Deploy FastAPI on Deta Space
|
||||
|
||||
In this section you will learn how to easily deploy a **FastAPI** application on <a href="https://www.deta.sh/?ref=fastapi" class="external-link" target="_blank">Deta</a> using the free plan. 🎁
|
||||
In this section you will learn how to easily deploy a **FastAPI** application on <a href="https://deta.space?ref=fastapi" class="external-link" target="_blank">Deta Space</a>, for free. 🎁
|
||||
|
||||
It will take you about **10 minutes**.
|
||||
It will take you about **10 minutes** to deploy an API that you can use. After that, you can optionally release it to anyone.
|
||||
|
||||
Let's dive in.
|
||||
|
||||
!!! info
|
||||
<a href="https://www.deta.sh/?ref=fastapi" class="external-link" target="_blank">Deta</a> is a **FastAPI** sponsor. 🎉
|
||||
<a href="https://deta.space?ref=fastapi" class="external-link" target="_blank">Deta</a> is a **FastAPI** sponsor. 🎉
|
||||
|
||||
## A basic **FastAPI** app
|
||||
## A simple **FastAPI** app
|
||||
|
||||
* Create a directory for your app, for example, `./fastapideta/` and enter into it.
|
||||
* To start, create an empty directory with the name of your app, for example `./fastapi-deta/`, and then navigate into it.
|
||||
|
||||
```console
|
||||
$ mkdir fastapi-deta
|
||||
$ cd fastapi-deta
|
||||
```
|
||||
|
||||
### FastAPI code
|
||||
|
||||
@@ -37,14 +44,12 @@ Now, in the same directory create a file `requirements.txt` with:
|
||||
|
||||
```text
|
||||
fastapi
|
||||
uvicorn[standard]
|
||||
```
|
||||
|
||||
!!! tip
|
||||
You don't need to install Uvicorn to deploy on Deta, although you would probably want to install it locally to test your app.
|
||||
|
||||
### Directory structure
|
||||
|
||||
You will now have one directory `./fastapideta/` with two files:
|
||||
You will now have a directory `./fastapi-deta/` with two files:
|
||||
|
||||
```
|
||||
.
|
||||
@@ -52,22 +57,23 @@ You will now have one directory `./fastapideta/` with two files:
|
||||
└── requirements.txt
|
||||
```
|
||||
|
||||
## Create a free Deta account
|
||||
## Create a free **Deta Space** account
|
||||
|
||||
Now create a <a href="https://www.deta.sh/?ref=fastapi" class="external-link" target="_blank">free account on Deta</a>, you just need an email and password.
|
||||
Next, create a free account on <a href="https://deta.space/signup?dev_mode=true&ref=fastapi" class="external-link" target="_blank">Deta Space</a>, you just need an email and password.
|
||||
|
||||
You don't even need a credit card, but make sure **Developer Mode** is enabled when you sign up.
|
||||
|
||||
You don't even need a credit card.
|
||||
|
||||
## Install the CLI
|
||||
|
||||
Once you have your account, install the Deta <abbr title="Command Line Interface application">CLI</abbr>:
|
||||
Once you have your account, install the Deta Space <abbr title="Command Line Interface application">CLI</abbr>:
|
||||
|
||||
=== "Linux, macOS"
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ curl -fsSL https://get.deta.dev/cli.sh | sh
|
||||
$ curl -fsSL https://get.deta.dev/space-cli.sh | sh
|
||||
```
|
||||
|
||||
</div>
|
||||
@@ -77,7 +83,7 @@ Once you have your account, install the Deta <abbr title="Command Line Interface
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ iwr https://get.deta.dev/cli.ps1 -useb | iex
|
||||
$ iwr https://get.deta.dev/space-cli.ps1 -useb | iex
|
||||
```
|
||||
|
||||
</div>
|
||||
@@ -89,95 +95,144 @@ In a new terminal, confirm that it was correctly installed with:
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ deta --help
|
||||
$ space --help
|
||||
|
||||
Deta command line interface for managing deta micros.
|
||||
Complete documentation available at https://docs.deta.sh
|
||||
Complete documentation available at https://deta.space/docs
|
||||
|
||||
Usage:
|
||||
deta [flags]
|
||||
deta [command]
|
||||
space [flags]
|
||||
space [command]
|
||||
|
||||
Available Commands:
|
||||
auth Change auth settings for a deta micro
|
||||
|
||||
help Help about any command
|
||||
link link code to project
|
||||
login login to space
|
||||
new create new project
|
||||
push push code for project
|
||||
release create release for a project
|
||||
validate validate spacefile in dir
|
||||
version Space CLI version
|
||||
...
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
!!! tip
|
||||
If you have problems installing the CLI, check the <a href="https://docs.deta.sh/docs/micros/getting_started?ref=fastapi" class="external-link" target="_blank">official Deta docs</a>.
|
||||
If you have problems installing the CLI, check the official <a href="https://deta.space/docs/en/basics/cli?ref=fastapi" class="external-link" target="_blank">Deta Space Documentation</a>.
|
||||
|
||||
## Login with the CLI
|
||||
|
||||
Now login to Deta from the CLI with:
|
||||
In order to authenticate your CLI with Deta Space, you will need an access token.
|
||||
|
||||
To obtain this token, open your <a href="https://deta.space/login?ref=fastapi" class="external-link" target="_blank">Deta Space Canvas</a>, open the **Teletype** (command bar at the bottom of the Canvas), and then click on **Settings**. From there, select **Generate Token** and copy the resulting token.
|
||||
|
||||
<img src="/img/deployment/deta/image03.png">
|
||||
|
||||
Now run `space login` from the Space CLI. Upon pasting the token into the CLI prompt and pressing enter, you should see a confirmation message.
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ deta login
|
||||
$ space login
|
||||
|
||||
Please, log in from the web page. Waiting..
|
||||
Logged in successfully.
|
||||
To authenticate the Space CLI with your Space account, generate a new access token in your Space settings and paste it below:
|
||||
|
||||
# Enter access token (41 chars) >$ *****************************************
|
||||
|
||||
👍 Login Successful!
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
This will open a web browser and authenticate automatically.
|
||||
## Create a new project in Space
|
||||
|
||||
## Deploy with Deta
|
||||
Now that you've authenticated with the Space CLI, use it to create a new <a href="https://deta.space/docs/en/basics/projects" class="external-link" target="_blank">Space Project</a>:
|
||||
|
||||
Next, deploy your application with the Deta CLI:
|
||||
```console
|
||||
$ space new
|
||||
|
||||
# What is your project's name? >$ fastapi-deta
|
||||
```
|
||||
|
||||
The Space CLI will ask you to name the project, we will call ours `fastapi-deta`.
|
||||
|
||||
Then, it will try to automatically detect which framework or language you are using, showing you what it finds. In our case it will identify the Python app with the following message, prompting you to confirm:
|
||||
|
||||
```console
|
||||
⚙️ No Spacefile found, trying to auto-detect configuration ...
|
||||
👇 Deta detected the following configuration:
|
||||
|
||||
Micros:
|
||||
name: fastapi-deta
|
||||
L src: .
|
||||
L engine: python3.9
|
||||
|
||||
# Do you want to bootstrap "fastapi-deta" with this configuration? (y/n)$ y
|
||||
```
|
||||
|
||||
After you confirm, your project will be created in Deta Space inside a special app called <a href="https://deta.space/docs/en/basics/projects#projects-in-builder?ref=fastapi" class="external-link" target="_blank">Builder</a>. Builder is a toolbox that helps you to create and manage your apps in Deta Space.
|
||||
|
||||
The CLI will also create a `Spacefile` locally in the `fastapi-deta` directory. The <a href="https://deta.space/docs/en/reference/spacefile?ref=fastapi" class="external-link" target="_blank">Spacefile</a> is a configuration file which tells Deta Space how to run your app. The `Spacefile` for your app will be as follows:
|
||||
|
||||
```yaml
|
||||
v: 0
|
||||
micros:
|
||||
- name: fastapi-deta
|
||||
src: .
|
||||
engine: python3.9
|
||||
```
|
||||
|
||||
It is a `yaml` file, and you can use it to add features like scheduled tasks or modify how your app functions, which we'll do later. To learn more, read <a href="https://deta.space/docs/en/reference/spacefile" class="external-link" target="_blank">the `Spacefile` documentation</a>.
|
||||
|
||||
!!! tip
|
||||
The Space CLI will also create a hidden `.space` folder in your local directory to link your local environment with Deta Space. This folder should not be included in your version control and will automatically be added to your `.gitignore` file, if you have initialized a Git repository.
|
||||
|
||||
## Define the run command in the Spacefile
|
||||
|
||||
The `run` command in the Spacefile tells Space what command should be executed to start your app. In this case it would be `uvicorn main:app`.
|
||||
|
||||
```diff
|
||||
v: 0
|
||||
micros:
|
||||
- name: fastapi-deta
|
||||
src: .
|
||||
engine: python3.9
|
||||
+ run: uvicorn main:app
|
||||
```
|
||||
|
||||
## Deploy to Deta Space
|
||||
|
||||
To get your FastAPI live in the cloud, use one more CLI command:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ deta new
|
||||
|
||||
Successfully created a new micro
|
||||
|
||||
// Notice the "endpoint" 🔍
|
||||
|
||||
{
|
||||
"name": "fastapideta",
|
||||
"runtime": "python3.7",
|
||||
"endpoint": "https://qltnci.deta.dev",
|
||||
"visor": "enabled",
|
||||
"http_auth": "enabled"
|
||||
}
|
||||
|
||||
Adding dependencies...
|
||||
|
||||
$ space push
|
||||
|
||||
---> 100%
|
||||
|
||||
build complete... created revision: satyr-jvjk
|
||||
|
||||
Successfully installed fastapi-0.61.1 pydantic-1.7.2 starlette-0.13.6
|
||||
✔ Successfully pushed your code and created a new Revision!
|
||||
ℹ Updating your development instance with the latest Revision, it will be available on your Canvas shortly.
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
You will see a JSON message similar to:
|
||||
|
||||
```JSON hl_lines="4"
|
||||
{
|
||||
"name": "fastapideta",
|
||||
"runtime": "python3.7",
|
||||
"endpoint": "https://qltnci.deta.dev",
|
||||
"visor": "enabled",
|
||||
"http_auth": "enabled"
|
||||
}
|
||||
```
|
||||
This command will package your code, upload all the necessary files to Deta Space, and run a remote build of your app, resulting in a **revision**. Whenever you run `space push` successfully, a live instance of your API is automatically updated with the latest revision.
|
||||
|
||||
!!! tip
|
||||
Your deployment will have a different `"endpoint"` URL.
|
||||
You can manage your <a href="https://deta.space/docs/en/basics/revisions#whats-a-revision" class="external-link" target="_blank">revisions</a> by opening your project in the Builder app. The live copy of your API will be visible under the **Develop** tab in Builder.
|
||||
|
||||
## Check it
|
||||
|
||||
Now open your browser in your `endpoint` URL. In the example above it was `https://qltnci.deta.dev`, but yours will be different.
|
||||
The live instance of your API will also be added automatically to your Canvas (the dashboard) on Deta Space.
|
||||
|
||||
You will see the JSON response from your FastAPI app:
|
||||
<img src="/img/deployment/deta/image04.png">
|
||||
|
||||
Click on the new app called `fastapi-deta`, and it will open your API in a new browser tab on a URL like `https://fastapi-deta-gj7ka8.deta.app/`.
|
||||
|
||||
You will get a JSON response from your FastAPI app:
|
||||
|
||||
```JSON
|
||||
{
|
||||
@@ -185,74 +240,152 @@ You will see the JSON response from your FastAPI app:
|
||||
}
|
||||
```
|
||||
|
||||
And now go to the `/docs` for your API, in the example above it would be `https://qltnci.deta.dev/docs`.
|
||||
And now you can head over to the `/docs` of your API. For this example, it would be `https://fastapi-deta-gj7ka8.deta.app/docs`.
|
||||
|
||||
It will show your docs like:
|
||||
|
||||
<img src="/img/deployment/deta/image01.png">
|
||||
<img src="/img/deployment/deta/image05.png">
|
||||
|
||||
## Enable public access
|
||||
|
||||
By default, Deta will handle authentication using cookies for your account.
|
||||
Deta will handle authentication for your account using cookies. By default, every app or API that you `push` or install to your Space is personal - it's only accessible to you.
|
||||
|
||||
But once you are ready, you can make it public with:
|
||||
But you can also make your API public using the `Spacefile` from earlier.
|
||||
|
||||
With a `public_routes` parameter, you can specify which paths of your API should be available to the public.
|
||||
|
||||
Set your `public_routes` to `"*"` to open every route of your API to the public:
|
||||
|
||||
```yaml
|
||||
v: 0
|
||||
micros:
|
||||
- name: fastapi-deta
|
||||
src: .
|
||||
engine: python3.9
|
||||
public_routes:
|
||||
- "/*"
|
||||
```
|
||||
|
||||
Then run `space push` again to update your live API on Deta Space.
|
||||
|
||||
Once it deploys, you can share your URL with anyone and they will be able to access your API. 🚀
|
||||
|
||||
## HTTPS
|
||||
|
||||
Congrats! You deployed your FastAPI app to Deta Space! 🎉 🍰
|
||||
|
||||
Also, notice that Deta Space correctly handles HTTPS for you, so you don't have to take care of that and can be sure that your users will have a secure encrypted connection. ✅ 🔒
|
||||
|
||||
## Create a release
|
||||
|
||||
Space also allows you to publish your API. When you publish it, anyone else can install their own copy of your API, in their own Deta Space cloud.
|
||||
|
||||
To do so, run `space release` in the Space CLI to create an **unlisted release**:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ deta auth disable
|
||||
$ space release
|
||||
|
||||
Successfully disabled http auth
|
||||
# Do you want to use the latest revision (buzzard-hczt)? (y/n)$ y
|
||||
|
||||
~ Creating a Release with the latest Revision
|
||||
|
||||
---> 100%
|
||||
|
||||
creating release...
|
||||
publishing release in edge locations..
|
||||
completed...
|
||||
released: fastapi-deta-exp-msbu
|
||||
https://deta.space/discovery/r/5kjhgyxewkdmtotx
|
||||
|
||||
Lift off -- successfully created a new Release!
|
||||
Your Release is available globally on 5 Deta Edges
|
||||
Anyone can install their own copy of your app.
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Now you can share that URL with anyone and they will be able to access your API. 🚀
|
||||
This command publishes your revision as a release and gives you a link. Anyone you give this link to can install your API.
|
||||
|
||||
## HTTPS
|
||||
|
||||
Congrats! You deployed your FastAPI app to Deta! 🎉 🍰
|
||||
You can also make your app publicly discoverable by creating a **listed release** with `space release --listed` in the Space CLI:
|
||||
|
||||
Also, notice that Deta correctly handles HTTPS for you, so you don't have to take care of that and can be sure that your clients will have a secure encrypted connection. ✅ 🔒
|
||||
<div class="termy">
|
||||
|
||||
## Check the Visor
|
||||
```console
|
||||
$ space release --listed
|
||||
|
||||
From your docs UI (they will be in a URL like `https://qltnci.deta.dev/docs`) send a request to your *path operation* `/items/{item_id}`.
|
||||
# Do you want to use the latest revision (buzzard-hczt)? (y/n)$ y
|
||||
|
||||
For example with ID `5`.
|
||||
~ Creating a listed Release with the latest Revision ...
|
||||
|
||||
Now go to <a href="https://web.deta.sh/" class="external-link" target="_blank">https://web.deta.sh</a>.
|
||||
creating release...
|
||||
publishing release in edge locations..
|
||||
completed...
|
||||
released: fastapi-deta-exp-msbu
|
||||
https://deta.space/discovery/@user/fastapi-deta
|
||||
|
||||
You will see there's a section to the left called <abbr title="it comes from Micro(server)">"Micros"</abbr> with each of your apps.
|
||||
Lift off -- successfully created a new Release!
|
||||
Your Release is available globally on 5 Deta Edges
|
||||
Anyone can install their own copy of your app.
|
||||
Listed on Discovery for others to find!
|
||||
```
|
||||
</div>
|
||||
|
||||
You will see a tab with "Details", and also a tab "Visor", go to the tab "Visor".
|
||||
This will allow anyone to find and install your app via <a href="https://deta.space/discovery?ref=fastapi" class="external-link" target="_blank">Deta Discovery</a>. Read more about <a href="https://deta.space/docs/en/basics/releases?ref=fastapi" class="external-link" target="_blank">releasing your app in the docs</a>.
|
||||
|
||||
In there you can inspect the recent requests sent to your app.
|
||||
## Check runtime logs
|
||||
|
||||
You can also edit them and re-play them.
|
||||
Deta Space also lets you inspect the logs of every app you build or install.
|
||||
|
||||
<img src="/img/deployment/deta/image02.png">
|
||||
Add some logging functionality to your app by adding a `print` statement to your `main.py` file.
|
||||
|
||||
```py
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/")
|
||||
def read_root():
|
||||
return {"Hello": "World"}
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int):
|
||||
print(item_id)
|
||||
return {"item_id": item_id}
|
||||
```
|
||||
|
||||
The code within the `read_item` function includes a print statement that will output the `item_id` that is included in the URL. Send a request to your _path operation_ `/items/{item_id}` from the docs UI (which will have a URL like `https://fastapi-deta-gj7ka8.deta.app/docs`), using an ID like `5` as an example.
|
||||
|
||||
Now go to your <a href="https://deta.space?ref=fastapi" class="external-link" target="_blank">Space's Canvas</a>. Click on the context menu (`...`) of your live app instance, and then click on **View Logs**. Here you can view your app's logs, sorted by time.
|
||||
|
||||
<img src="/img/deployment/deta/image06.png">
|
||||
|
||||
## Learn more
|
||||
|
||||
At some point, you will probably want to store some data for your app in a way that persists through time. For that you can use <a href="https://docs.deta.sh/docs/base/py_tutorial?ref=fastapi" class="external-link" target="_blank">Deta Base</a>, it also has a generous **free tier**.
|
||||
At some point, you will probably want to store some data for your app in a way that persists through time. For that you can use <a href="https://deta.space/docs/en/basics/data#deta-base?ref=fastapi" class="external-link" target="_blank">Deta Base</a> and <a href="https://deta.space/docs/en/basics/data#deta-drive?ref=fastapi" class="external-link" target="_blank">Deta Drive</a>, both of which have a generous **free tier**.
|
||||
|
||||
You can also read more in the <a href="https://deta.space/docs/?ref=fastapi" class="external-link" target="_blank">Deta Space Documentation</a>.
|
||||
|
||||
!!! tip
|
||||
If you have any Deta related questions, comments, or feedback, head to the <a href="https://go.deta.dev/discord" class="external-link" target="_blank">Deta Discord server</a>.
|
||||
|
||||
You can also read more in the <a href="https://docs.deta.sh?ref=fastapi" class="external-link" target="_blank">Deta Docs</a>.
|
||||
|
||||
## Deployment Concepts
|
||||
|
||||
Coming back to the concepts we discussed in [Deployments Concepts](./concepts.md){.internal-link target=_blank}, here's how each of them would be handled with Deta:
|
||||
Coming back to the concepts we discussed in [Deployments Concepts](./concepts.md){.internal-link target=_blank}, here's how each of them would be handled with Deta Space:
|
||||
|
||||
* **HTTPS**: Handled by Deta, they will give you a subdomain and handle HTTPS automatically.
|
||||
* **Running on startup**: Handled by Deta, as part of their service.
|
||||
* **Restarts**: Handled by Deta, as part of their service.
|
||||
* **Replication**: Handled by Deta, as part of their service.
|
||||
* **Memory**: Limit predefined by Deta, you could contact them to increase it.
|
||||
* **Previous steps before starting**: Not directly supported, you could make it work with their Cron system or additional scripts.
|
||||
- **HTTPS**: Handled by Deta Space, they will give you a subdomain and handle HTTPS automatically.
|
||||
- **Running on startup**: Handled by Deta Space, as part of their service.
|
||||
- **Restarts**: Handled by Deta Space, as part of their service.
|
||||
- **Replication**: Handled by Deta Space, as part of their service.
|
||||
- **Authentication**: Handled by Deta Space, as part of their service.
|
||||
- **Memory**: Limit predefined by Deta Space, you could contact them to increase it.
|
||||
- **Previous steps before starting**: Can be configured using the <a href="https://deta.space/docs/en/reference/spacefile?ref=fastapi" class="external-link" target="_blank">`Spacefile`</a>.
|
||||
|
||||
!!! note
|
||||
Deta is designed to make it easy (and free) to deploy simple applications quickly.
|
||||
Deta Space is designed to make it easy and free to build cloud applications for yourself. Then you can optionally share them with anyone.
|
||||
|
||||
It can simplify several use cases, but at the same time, it doesn't support others, like using external databases (apart from Deta's own NoSQL database system), custom virtual machines, etc.
|
||||
|
||||
You can read more details in the <a href="https://docs.deta.sh/docs/micros/about/" class="external-link" target="_blank">Deta docs</a> to see if it's the right choice for you.
|
||||
You can read more details in the <a href="https://deta.space/docs/en/basics/micros?ref=fastapi" class="external-link" target="_blank">Deta Space Documentation</a> to see if it's the right choice for you.
|
||||
|
||||
@@ -189,8 +189,6 @@ With **FastAPI** you get all of **Pydantic**'s features (as FastAPI is based on
|
||||
* If you know Python types you know how to use Pydantic.
|
||||
* 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/" 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.
|
||||
|
||||
BIN
docs/en/docs/img/deployment/deta/image03.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
docs/en/docs/img/deployment/deta/image04.png
Normal file
|
After Width: | Height: | Size: 49 KiB |
BIN
docs/en/docs/img/deployment/deta/image05.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
docs/en/docs/img/deployment/deta/image06.png
Normal file
|
After Width: | Height: | Size: 103 KiB |
BIN
docs/en/docs/img/sponsors/flint.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
docs/en/docs/img/sponsors/platform-sh-banner.png
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
BIN
docs/en/docs/img/sponsors/platform-sh.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
@@ -445,7 +445,6 @@ To understand more about it, see the section <a href="https://fastapi.tiangolo.c
|
||||
|
||||
Used by Pydantic:
|
||||
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - for faster JSON <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>.
|
||||
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - for email validation.
|
||||
|
||||
Used by Starlette:
|
||||
|
||||
@@ -3,6 +3,161 @@
|
||||
## Latest Changes
|
||||
|
||||
|
||||
## 0.98.0
|
||||
|
||||
### Features
|
||||
|
||||
* ✨ Allow disabling `redirect_slashes` at the FastAPI app level. PR [#3432](https://github.com/tiangolo/fastapi/pull/3432) by [@cyberlis](https://github.com/cyberlis).
|
||||
|
||||
### Docs
|
||||
|
||||
* 📝 Update docs on Pydantic using ujson internally. PR [#5804](https://github.com/tiangolo/fastapi/pull/5804) by [@mvasilkov](https://github.com/mvasilkov).
|
||||
* ✏ Rewording in `docs/en/docs/tutorial/debugging.md`. PR [#9581](https://github.com/tiangolo/fastapi/pull/9581) by [@ivan-abc](https://github.com/ivan-abc).
|
||||
* 📝 Add german blog post (Domain-driven Design mit Python und FastAPI). PR [#9261](https://github.com/tiangolo/fastapi/pull/9261) by [@msander](https://github.com/msander).
|
||||
* ✏️ Tweak wording in `docs/en/docs/tutorial/security/index.md`. PR [#9561](https://github.com/tiangolo/fastapi/pull/9561) by [@jyothish-mohan](https://github.com/jyothish-mohan).
|
||||
* 📝 Update `Annotated` notes in `docs/en/docs/tutorial/schema-extra-example.md`. PR [#9620](https://github.com/tiangolo/fastapi/pull/9620) by [@Alexandrhub](https://github.com/Alexandrhub).
|
||||
* ✏️ Fix typo `Annotation` -> `Annotated` in `docs/en/docs/tutorial/query-params-str-validations.md`. PR [#9625](https://github.com/tiangolo/fastapi/pull/9625) by [@mccricardo](https://github.com/mccricardo).
|
||||
* 📝 Use in memory database for testing SQL in docs. PR [#1223](https://github.com/tiangolo/fastapi/pull/1223) by [@HarshaLaxman](https://github.com/HarshaLaxman).
|
||||
|
||||
### Translations
|
||||
|
||||
* 🌐 Add Russian translation for `docs/ru/docs/tutorial/metadata.md`. PR [#9681](https://github.com/tiangolo/fastapi/pull/9681) by [@TabarakoAkula](https://github.com/TabarakoAkula).
|
||||
* 🌐 Fix typo in Spanish translation for `docs/es/docs/tutorial/first-steps.md`. PR [#9571](https://github.com/tiangolo/fastapi/pull/9571) by [@lilidl-nft](https://github.com/lilidl-nft).
|
||||
* 🌐 Add Russian translation for `docs/tutorial/path-operation-configuration.md`. PR [#9696](https://github.com/tiangolo/fastapi/pull/9696) by [@TabarakoAkula](https://github.com/TabarakoAkula).
|
||||
* 🌐 Add Chinese translation for `docs/zh/docs/advanced/security/index.md`. PR [#9666](https://github.com/tiangolo/fastapi/pull/9666) by [@lordqyxz](https://github.com/lordqyxz).
|
||||
* 🌐 Add Chinese translations for `docs/zh/docs/advanced/settings.md`. PR [#9652](https://github.com/tiangolo/fastapi/pull/9652) by [@ChoyeonChern](https://github.com/ChoyeonChern).
|
||||
* 🌐 Add Chinese translations for `docs/zh/docs/advanced/websockets.md`. PR [#9651](https://github.com/tiangolo/fastapi/pull/9651) by [@ChoyeonChern](https://github.com/ChoyeonChern).
|
||||
* 🌐 Add Chinese translation for `docs/zh/docs/tutorial/testing.md`. PR [#9641](https://github.com/tiangolo/fastapi/pull/9641) by [@wdh99](https://github.com/wdh99).
|
||||
* 🌐 Add Russian translation for `docs/tutorial/extra-models.md`. PR [#9619](https://github.com/tiangolo/fastapi/pull/9619) by [@ivan-abc](https://github.com/ivan-abc).
|
||||
* 🌐 Add Russian translation for `docs/tutorial/cors.md`. PR [#9608](https://github.com/tiangolo/fastapi/pull/9608) by [@ivan-abc](https://github.com/ivan-abc).
|
||||
* 🌐 Add Polish translation for `docs/pl/docs/features.md`. PR [#5348](https://github.com/tiangolo/fastapi/pull/5348) by [@mbroton](https://github.com/mbroton).
|
||||
* 🌐 Add Russian translation for `docs/ru/docs/tutorial/body-nested-models.md`. PR [#9605](https://github.com/tiangolo/fastapi/pull/9605) by [@Alexandrhub](https://github.com/Alexandrhub).
|
||||
|
||||
### Internal
|
||||
|
||||
* ⬆ Bump ruff from 0.0.272 to 0.0.275. PR [#9721](https://github.com/tiangolo/fastapi/pull/9721) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
||||
* ⬆ Update uvicorn[standard] requirement from <0.21.0,>=0.12.0 to >=0.12.0,<0.23.0. PR [#9463](https://github.com/tiangolo/fastapi/pull/9463) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
||||
* ⬆ Bump mypy from 1.3.0 to 1.4.0. PR [#9719](https://github.com/tiangolo/fastapi/pull/9719) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
||||
* ⬆ Update pre-commit requirement from <3.0.0,>=2.17.0 to >=2.17.0,<4.0.0. PR [#9251](https://github.com/tiangolo/fastapi/pull/9251) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
||||
* ⬆ Bump pypa/gh-action-pypi-publish from 1.8.5 to 1.8.6. PR [#9482](https://github.com/tiangolo/fastapi/pull/9482) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
||||
* ✏️ Fix tooltips for light/dark theme toggler in docs. PR [#9588](https://github.com/tiangolo/fastapi/pull/9588) by [@pankaj1707k](https://github.com/pankaj1707k).
|
||||
* 🔧 Set minimal hatchling version needed to build the package. PR [#9240](https://github.com/tiangolo/fastapi/pull/9240) by [@mgorny](https://github.com/mgorny).
|
||||
* 📝 Add repo link to PyPI. PR [#9559](https://github.com/tiangolo/fastapi/pull/9559) by [@JacobCoffee](https://github.com/JacobCoffee).
|
||||
* ✏️ Fix typos in data for tests. PR [#4958](https://github.com/tiangolo/fastapi/pull/4958) by [@ryanrussell](https://github.com/ryanrussell).
|
||||
* 🔧 Update sponsors, add Flint. PR [#9699](https://github.com/tiangolo/fastapi/pull/9699) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 👷 Lint in CI only once, only with one version of Python, run tests with all of them. PR [#9686](https://github.com/tiangolo/fastapi/pull/9686) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
## 0.97.0
|
||||
|
||||
### Features
|
||||
|
||||
* ✨ Add support for `dependencies` in WebSocket routes. PR [#4534](https://github.com/tiangolo/fastapi/pull/4534) by [@paulo-raca](https://github.com/paulo-raca).
|
||||
* ✨ Add exception handler for `WebSocketRequestValidationError` (which also allows to override it). PR [#6030](https://github.com/tiangolo/fastapi/pull/6030) by [@kristjanvalur](https://github.com/kristjanvalur).
|
||||
|
||||
### Refactors
|
||||
|
||||
* ⬆️ Upgrade and fully migrate to Ruff, remove isort, includes a couple of tweaks suggested by the new version of Ruff. PR [#9660](https://github.com/tiangolo/fastapi/pull/9660) by [@tiangolo](https://github.com/tiangolo).
|
||||
* ♻️ Update internal type annotations and upgrade mypy. PR [#9658](https://github.com/tiangolo/fastapi/pull/9658) by [@tiangolo](https://github.com/tiangolo).
|
||||
* ♻️ Simplify `AsyncExitStackMiddleware` as without Python 3.6 `AsyncExitStack` is always available. PR [#9657](https://github.com/tiangolo/fastapi/pull/9657) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
### Upgrades
|
||||
|
||||
* ⬆️ Upgrade Black. PR [#9661](https://github.com/tiangolo/fastapi/pull/9661) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
### Internal
|
||||
|
||||
* 💚 Update CI cache to fix installs when dependencies change. PR [#9659](https://github.com/tiangolo/fastapi/pull/9659) by [@tiangolo](https://github.com/tiangolo).
|
||||
* ⬇️ Separate requirements for development into their own requirements.txt files, they shouldn't be extras. PR [#9655](https://github.com/tiangolo/fastapi/pull/9655) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
## 0.96.1
|
||||
|
||||
### Fixes
|
||||
|
||||
* 🐛 Fix `HTTPException` header type annotations. PR [#9648](https://github.com/tiangolo/fastapi/pull/9648) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 🐛 Fix OpenAPI model fields int validations, `gte` to `ge`. PR [#9635](https://github.com/tiangolo/fastapi/pull/9635) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
### Upgrades
|
||||
|
||||
* 📌 Update minimum version of Pydantic to >=1.7.4. This fixes an issue when trying to use an old version of Pydantic. PR [#9567](https://github.com/tiangolo/fastapi/pull/9567) by [@Kludex](https://github.com/Kludex).
|
||||
|
||||
### Refactors
|
||||
|
||||
* ♻ Remove `media_type` from `ORJSONResponse` as it's inherited from the parent class. PR [#5805](https://github.com/tiangolo/fastapi/pull/5805) by [@Kludex](https://github.com/Kludex).
|
||||
* ♻ Instantiate `HTTPException` only when needed, optimization refactor. PR [#5356](https://github.com/tiangolo/fastapi/pull/5356) by [@pawamoy](https://github.com/pawamoy).
|
||||
|
||||
### Docs
|
||||
|
||||
* 🔥 Remove link to Pydantic's benchmark, as it was removed there. PR [#5811](https://github.com/tiangolo/fastapi/pull/5811) by [@Kludex](https://github.com/Kludex).
|
||||
|
||||
### Translations
|
||||
|
||||
* 🌐 Fix spelling in Indonesian translation of `docs/id/docs/tutorial/index.md`. PR [#5635](https://github.com/tiangolo/fastapi/pull/5635) by [@purwowd](https://github.com/purwowd).
|
||||
* 🌐 Add Russian translation for `docs/ru/docs/tutorial/index.md`. PR [#5896](https://github.com/tiangolo/fastapi/pull/5896) by [@Wilidon](https://github.com/Wilidon).
|
||||
* 🌐 Add Chinese translations for `docs/zh/docs/advanced/response-change-status-code.md` and `docs/zh/docs/advanced/response-headers.md`. PR [#9544](https://github.com/tiangolo/fastapi/pull/9544) by [@ChoyeonChern](https://github.com/ChoyeonChern).
|
||||
* 🌐 Add Russian translation for `docs/ru/docs/tutorial/schema-extra-example.md`. PR [#9621](https://github.com/tiangolo/fastapi/pull/9621) by [@Alexandrhub](https://github.com/Alexandrhub).
|
||||
|
||||
### Internal
|
||||
|
||||
* 🔧 Add sponsor Platform.sh. PR [#9650](https://github.com/tiangolo/fastapi/pull/9650) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 👷 Add custom token to Smokeshow and Preview Docs for download-artifact, to prevent API rate limits. PR [#9646](https://github.com/tiangolo/fastapi/pull/9646) by [@tiangolo](https://github.com/tiangolo).
|
||||
* 👷 Add custom tokens for GitHub Actions to avoid rate limits. PR [#9647](https://github.com/tiangolo/fastapi/pull/9647) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
## 0.96.0
|
||||
|
||||
### Features
|
||||
|
||||
* ⚡ Update `create_cloned_field` to use a global cache and improve startup performance. PR [#4645](https://github.com/tiangolo/fastapi/pull/4645) by [@madkinsz](https://github.com/madkinsz) and previous original PR by [@huonw](https://github.com/huonw).
|
||||
|
||||
### Docs
|
||||
|
||||
* 📝 Update Deta deployment tutorial for compatibility with Deta Space. PR [#6004](https://github.com/tiangolo/fastapi/pull/6004) by [@mikBighne98](https://github.com/mikBighne98).
|
||||
* ✏️ Fix typo in Deta deployment tutorial. PR [#9501](https://github.com/tiangolo/fastapi/pull/9501) by [@lemonyte](https://github.com/lemonyte).
|
||||
|
||||
### Translations
|
||||
|
||||
* 🌐 Add Russian translation for `docs/tutorial/body.md`. PR [#3885](https://github.com/tiangolo/fastapi/pull/3885) by [@solomein-sv](https://github.com/solomein-sv).
|
||||
* 🌐 Add Russian translation for `docs/ru/docs/tutorial/static-files.md`. PR [#9580](https://github.com/tiangolo/fastapi/pull/9580) by [@Alexandrhub](https://github.com/Alexandrhub).
|
||||
* 🌐 Add Russian translation for `docs/ru/docs/tutorial/query-params.md`. PR [#9584](https://github.com/tiangolo/fastapi/pull/9584) by [@Alexandrhub](https://github.com/Alexandrhub).
|
||||
* 🌐 Add Russian translation for `docs/ru/docs/tutorial/first-steps.md`. PR [#9471](https://github.com/tiangolo/fastapi/pull/9471) by [@AGolicyn](https://github.com/AGolicyn).
|
||||
* 🌐 Add Russian translation for `docs/ru/docs/tutorial/debugging.md`. PR [#9579](https://github.com/tiangolo/fastapi/pull/9579) by [@Alexandrhub](https://github.com/Alexandrhub).
|
||||
* 🌐 Add Russian translation for `docs/ru/docs/tutorial/path-params.md`. PR [#9519](https://github.com/tiangolo/fastapi/pull/9519) by [@AGolicyn](https://github.com/AGolicyn).
|
||||
* 🌐 Add Chinese translation for `docs/zh/docs/tutorial/static-files.md`. PR [#9436](https://github.com/tiangolo/fastapi/pull/9436) by [@wdh99](https://github.com/wdh99).
|
||||
* 🌐 Update Spanish translation including new illustrations in `docs/es/docs/async.md`. PR [#9483](https://github.com/tiangolo/fastapi/pull/9483) by [@andresbermeoq](https://github.com/andresbermeoq).
|
||||
* 🌐 Add Russian translation for `docs/ru/docs/tutorial/path-params-numeric-validations.md`. PR [#9563](https://github.com/tiangolo/fastapi/pull/9563) by [@ivan-abc](https://github.com/ivan-abc).
|
||||
* 🌐 Add Russian translation for `docs/ru/docs/deployment/concepts.md`. PR [#9577](https://github.com/tiangolo/fastapi/pull/9577) by [@Xewus](https://github.com/Xewus).
|
||||
* 🌐 Add Russian translation for `docs/ru/docs/tutorial/body-multiple-params.md`. PR [#9586](https://github.com/tiangolo/fastapi/pull/9586) by [@Alexandrhub](https://github.com/Alexandrhub).
|
||||
|
||||
### Internal
|
||||
|
||||
* 👥 Update FastAPI People. PR [#9602](https://github.com/tiangolo/fastapi/pull/9602) by [@github-actions[bot]](https://github.com/apps/github-actions).
|
||||
* 🔧 Update sponsors, remove InvestSuite. PR [#9612](https://github.com/tiangolo/fastapi/pull/9612) by [@tiangolo](https://github.com/tiangolo).
|
||||
|
||||
## 0.95.2
|
||||
|
||||
* ⬆️ Upgrade Starlette version to `>=0.27.0` for a security release. PR [#9541](https://github.com/tiangolo/fastapi/pull/9541) by [@tiangolo](https://github.com/tiangolo). Details on [Starlette's security advisory](https://github.com/encode/starlette/security/advisories/GHSA-v5gw-mw7f-84px).
|
||||
|
||||
### Translations
|
||||
|
||||
* 🌐 Add Portuguese translation for `docs/pt/docs/advanced/events.md`. PR [#9326](https://github.com/tiangolo/fastapi/pull/9326) by [@oandersonmagalhaes](https://github.com/oandersonmagalhaes).
|
||||
* 🌐 Add Russian translation for `docs/ru/docs/deployment/manually.md`. PR [#9417](https://github.com/tiangolo/fastapi/pull/9417) by [@Xewus](https://github.com/Xewus).
|
||||
* 🌐 Add setup for translations to Lao. PR [#9396](https://github.com/tiangolo/fastapi/pull/9396) by [@TheBrown](https://github.com/TheBrown).
|
||||
* 🌐 Add Russian translation for `docs/ru/docs/tutorial/testing.md`. PR [#9403](https://github.com/tiangolo/fastapi/pull/9403) by [@Xewus](https://github.com/Xewus).
|
||||
* 🌐 Add Russian translation for `docs/ru/docs/deployment/https.md`. PR [#9428](https://github.com/tiangolo/fastapi/pull/9428) by [@Xewus](https://github.com/Xewus).
|
||||
* ✏ Fix command to install requirements in Windows. PR [#9445](https://github.com/tiangolo/fastapi/pull/9445) by [@MariiaRomanuik](https://github.com/MariiaRomanuik).
|
||||
* 🌐 Add French translation for `docs/fr/docs/advanced/response-directly.md`. PR [#9415](https://github.com/tiangolo/fastapi/pull/9415) by [@axel584](https://github.com/axel584).
|
||||
* 🌐 Initiate Czech translation setup. PR [#9288](https://github.com/tiangolo/fastapi/pull/9288) by [@3p1463k](https://github.com/3p1463k).
|
||||
* ✏ Fix typo in Portuguese docs for `docs/pt/docs/index.md`. PR [#9337](https://github.com/tiangolo/fastapi/pull/9337) by [@lucasbalieiro](https://github.com/lucasbalieiro).
|
||||
* 🌐 Add Russian translation for `docs/ru/docs/tutorial/response-status-code.md`. PR [#9370](https://github.com/tiangolo/fastapi/pull/9370) by [@nadia3373](https://github.com/nadia3373).
|
||||
|
||||
### Internal
|
||||
|
||||
* 🐛 Fix `flask.escape` warning for internal tests. PR [#9468](https://github.com/tiangolo/fastapi/pull/9468) by [@samuelcolvin](https://github.com/samuelcolvin).
|
||||
* ✅ Refactor 2 tests, for consistency and simplification. PR [#9504](https://github.com/tiangolo/fastapi/pull/9504) by [@tiangolo](https://github.com/tiangolo).
|
||||
* ✅ Refactor OpenAPI tests, prepare for Pydantic v2. PR [#9503](https://github.com/tiangolo/fastapi/pull/9503) by [@tiangolo](https://github.com/tiangolo).
|
||||
* ⬆ Bump dawidd6/action-download-artifact from 2.26.0 to 2.27.0. PR [#9394](https://github.com/tiangolo/fastapi/pull/9394) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
||||
* 💚 Disable setup-python pip cache in CI. PR [#9438](https://github.com/tiangolo/fastapi/pull/9438) by [@tiangolo](https://github.com/tiangolo).
|
||||
* ⬆ Bump pypa/gh-action-pypi-publish from 1.6.4 to 1.8.5. PR [#9346](https://github.com/tiangolo/fastapi/pull/9346) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
||||
|
||||
## 0.95.1
|
||||
|
||||
### Fixes
|
||||
|
||||
@@ -64,7 +64,7 @@ from myapp import app
|
||||
# Some more code
|
||||
```
|
||||
|
||||
in that case, the automatic variable inside of `myapp.py` will not have the variable `__name__` with a value of `"__main__"`.
|
||||
in that case, the automatically created variable inside of `myapp.py` will not have the variable `__name__` with a value of `"__main__"`.
|
||||
|
||||
So, the line:
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ To achieve that, first import:
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
In versions of Python below Python 3.9 you import `Annotation` from `typing_extensions`.
|
||||
In versions of Python below Python 3.9 you import `Annotated` from `typing_extensions`.
|
||||
|
||||
It will already be installed with FastAPI.
|
||||
|
||||
|
||||
@@ -86,6 +86,9 @@ Here we pass an `example` of the data expected in `Body()`:
|
||||
|
||||
=== "Python 3.10+ non-Annotated"
|
||||
|
||||
!!! tip
|
||||
Prefer to use the `Annotated` version if possible.
|
||||
|
||||
```Python hl_lines="18-23"
|
||||
{!> ../../../docs_src/schema_extra_example/tutorial003_py310.py!}
|
||||
```
|
||||
@@ -138,6 +141,9 @@ Each specific example `dict` in the `examples` can contain:
|
||||
|
||||
=== "Python 3.10+ non-Annotated"
|
||||
|
||||
!!! tip
|
||||
Prefer to use the `Annotated` version if possible.
|
||||
|
||||
```Python hl_lines="19-45"
|
||||
{!> ../../../docs_src/schema_extra_example/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
@@ -26,7 +26,7 @@ That's what all the systems with "login with Facebook, Google, Twitter, GitHub"
|
||||
|
||||
### OAuth 1
|
||||
|
||||
There was an OAuth 1, which is very different from OAuth2, and more complex, as it included directly specifications on how to encrypt the communication.
|
||||
There was an OAuth 1, which is very different from OAuth2, and more complex, as it included direct specifications on how to encrypt the communication.
|
||||
|
||||
It is not very popular or used nowadays.
|
||||
|
||||
|
||||
@@ -11,14 +11,14 @@ theme:
|
||||
accent: amber
|
||||
toggle:
|
||||
icon: material/lightbulb
|
||||
name: Switch to light mode
|
||||
name: Switch to dark mode
|
||||
- media: '(prefers-color-scheme: dark)'
|
||||
scheme: slate
|
||||
primary: teal
|
||||
accent: amber
|
||||
toggle:
|
||||
icon: material/lightbulb-outline
|
||||
name: Switch to dark mode
|
||||
name: Switch to light mode
|
||||
features:
|
||||
- search.suggest
|
||||
- search.highlight
|
||||
@@ -40,6 +40,7 @@ nav:
|
||||
- Languages:
|
||||
- en: /
|
||||
- az: /az/
|
||||
- cs: /cs/
|
||||
- de: /de/
|
||||
- em: /em/
|
||||
- es: /es/
|
||||
@@ -51,6 +52,7 @@ nav:
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- lo: /lo/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
@@ -211,6 +213,8 @@ extra:
|
||||
name: en - English
|
||||
- link: /az/
|
||||
name: az
|
||||
- link: /cs/
|
||||
name: cs
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /em/
|
||||
@@ -233,6 +237,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /lo/
|
||||
name: lo - ພາສາລາວ
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
|
||||
@@ -28,6 +28,12 @@
|
||||
<img class="sponsor-image" src="/img/sponsors/cryptapi-banner.svg" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="item">
|
||||
<a title="Build, run and scale your apps on a modern, reliable, and secure PaaS." style="display: block; position: relative;" href="https://platform.sh/try-it-now/?utm_source=fastapi-signup&utm_medium=banner&utm_campaign=FastAPI-signup-June-2023" target="_blank">
|
||||
<span class="sponsor-badge">sponsor</span>
|
||||
<img class="sponsor-image" src="/img/sponsors/platform-sh-banner.png" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -104,24 +104,40 @@ Para entender las diferencias, imagina la siguiente historia sobre hamburguesas:
|
||||
|
||||
Vas con la persona que te gusta 😍 a pedir comida rápida 🍔, haces cola mientras el cajero 💁 recoge los pedidos de las personas de delante tuyo.
|
||||
|
||||
<img src="https://fastapi.tiangolo.com/img/async/concurrent-burgers/concurrent-burgers-01.png" alt="illustration">
|
||||
|
||||
Llega tu turno, haces tu pedido de 2 hamburguesas impresionantes para esa persona 😍 y para ti.
|
||||
|
||||
Pagas 💸.
|
||||
<img src="https://fastapi.tiangolo.com/img/async/concurrent-burgers/concurrent-burgers-02.png" alt="illustration">
|
||||
|
||||
El cajero 💁 le dice algo al chico de la cocina 👨🍳 para que sepa que tiene que preparar tus hamburguesas 🍔 (a pesar de que actualmente está preparando las de los clientes anteriores).
|
||||
|
||||
<img src="https://fastapi.tiangolo.com/img/async/concurrent-burgers/concurrent-burgers-03.png" alt="illustration">
|
||||
|
||||
Pagas 💸.
|
||||
El cajero 💁 te da el número de tu turno.
|
||||
|
||||
<img src="https://fastapi.tiangolo.com/img/async/concurrent-burgers/concurrent-burgers-04.png" alt="illustration">
|
||||
|
||||
Mientras esperas, vas con esa persona 😍 y eliges una mesa, se sientan y hablan durante un rato largo (ya que las hamburguesas son muy impresionantes y necesitan un rato para prepararse ✨🍔✨).
|
||||
|
||||
Mientras te sientas en la mesa con esa persona 😍, esperando las hamburguesas 🍔, puedes disfrutar ese tiempo admirando lo increíble, inteligente, y bien que se ve ✨😍✨.
|
||||
|
||||
<img src="https://fastapi.tiangolo.com/img/async/concurrent-burgers/concurrent-burgers-05.png" alt="illustration">
|
||||
|
||||
Mientras esperas y hablas con esa persona 😍, de vez en cuando, verificas el número del mostrador para ver si ya es tu turno.
|
||||
|
||||
Al final, en algún momento, llega tu turno. Vas al mostrador, coges tus hamburguesas 🍔 y vuelves a la mesa.
|
||||
|
||||
<img src="https://fastapi.tiangolo.com/img/async/concurrent-burgers/concurrent-burgers-06.png" alt="illustration">
|
||||
|
||||
Tú y esa persona 😍 se comen las hamburguesas 🍔 y la pasan genial ✨.
|
||||
|
||||
<img src="https://fastapi.tiangolo.com/img/async/concurrent-burgers/concurrent-burgers-07.png" alt="illustration">
|
||||
|
||||
!!! info
|
||||
Las ilustraciones fueron creados por <a href="https://www.instagram.com/ketrinadrawsalot" class="external-link" target="_blank">Ketrina Thompson</a>. 🎨
|
||||
|
||||
---
|
||||
|
||||
Imagina que eres el sistema / programa 🤖 en esa historia.
|
||||
@@ -150,26 +166,41 @@ Haces la cola mientras varios cajeros (digamos 8) que a la vez son cocineros
|
||||
|
||||
Todos los que están antes de ti están esperando 🕙 que sus hamburguesas 🍔 estén listas antes de dejar el mostrador porque cada uno de los 8 cajeros prepara la hamburguesa de inmediato antes de recibir el siguiente pedido.
|
||||
|
||||
<img src="https://fastapi.tiangolo.com/img/async/parallel-burgers/parallel-burgers-01.png" alt="illustration">
|
||||
|
||||
Entonces finalmente es tu turno, haces tu pedido de 2 hamburguesas 🍔 impresionantes para esa persona 😍 y para ti.
|
||||
|
||||
Pagas 💸.
|
||||
|
||||
<img src="https://fastapi.tiangolo.com/img/async/parallel-burgers/parallel-burgers-02.png" alt="illustration">
|
||||
|
||||
El cajero va a la cocina 👨🍳.
|
||||
|
||||
Esperas, de pie frente al mostrador 🕙, para que nadie más recoja tus hamburguesas 🍔, ya que no hay números para los turnos.
|
||||
|
||||
<img src="https://fastapi.tiangolo.com/img/async/parallel-burgers/parallel-burgers-03.png" alt="illustration">
|
||||
|
||||
Como tu y esa persona 😍 están ocupados en impedir que alguien se ponga delante y recoja tus hamburguesas apenas llegan 🕙, tampoco puedes prestarle atención a esa persona 😞.
|
||||
|
||||
Este es un trabajo "síncrono", estás "sincronizado" con el cajero / cocinero 👨🍳. Tienes que esperar y estar allí en el momento exacto en que el cajero / cocinero 👨🍳 termina las hamburguesas 🍔 y te las da, o de lo contrario, alguien más podría cogerlas.
|
||||
|
||||
<img src="https://fastapi.tiangolo.com/img/async/parallel-burgers/parallel-burgers-04.png" alt="illustration">
|
||||
|
||||
Luego, el cajero / cocinero 👨🍳 finalmente regresa con tus hamburguesas 🍔, después de mucho tiempo esperando 🕙 frente al mostrador.
|
||||
|
||||
<img src="https://fastapi.tiangolo.com/img/async/parallel-burgers/parallel-burgers-05.png" alt="illustration">
|
||||
|
||||
Cojes tus hamburguesas 🍔 y vas a la mesa con esa persona 😍.
|
||||
|
||||
Sólo las comes y listo 🍔 ⏹.
|
||||
|
||||
<img src="https://fastapi.tiangolo.com/img/async/parallel-burgers/parallel-burgers-06.png" alt="illustration">
|
||||
|
||||
No has hablado ni coqueteado mucho, ya que has pasado la mayor parte del tiempo esperando 🕙 frente al mostrador 😞.
|
||||
|
||||
!!! info
|
||||
Las ilustraciones fueron creados por <a href="https://www.instagram.com/ketrinadrawsalot" class="external-link" target="_blank">Ketrina Thompson</a>. 🎨
|
||||
|
||||
---
|
||||
|
||||
En este escenario de las hamburguesas paralelas, tú eres un sistema / programa 🤖 con dos procesadores (tú y la persona que te gusta 😍), ambos esperando 🕙 y dedicando su atención ⏯ a estar "esperando en el mostrador" 🕙 durante mucho tiempo.
|
||||
@@ -240,7 +271,7 @@ Pero en este caso, si pudieras traer a los 8 ex cajeros / cocineros / ahora limp
|
||||
|
||||
En este escenario, cada uno de los limpiadores (incluido tú) sería un procesador, haciendo su parte del trabajo.
|
||||
|
||||
Y como la mayor parte del tiempo de ejecución lo coge el trabajo real (en lugar de esperar), y el trabajo en un sistema lo realiza una <abbr title = "Central Processing Unit. En español: Unidad Central de Procesamiento."> CPU </abbr>, a estos problemas se les llama "<abbr title="En español: atado a CPU.">CPU bond</abbr>".
|
||||
Y como la mayor parte del tiempo de ejecución lo coge el trabajo real (en lugar de esperar), y el trabajo en un sistema lo realiza una <abbr title = "Central Processing Unit. En español: Unidad Central de Procesamiento."> CPU </abbr>, a estos problemas se les llama "<abbr title="En español: atado a CPU.">CPU bound</abbr>".
|
||||
|
||||
---
|
||||
|
||||
@@ -257,7 +288,7 @@ Por ejemplo:
|
||||
|
||||
Con **FastAPI** puedes aprovechar la concurrencia que es muy común para el desarrollo web (atractivo principal de NodeJS).
|
||||
|
||||
Pero también puedes aprovechar los beneficios del paralelismo y el multiprocesamiento (tener múltiples procesos ejecutándose en paralelo) para cargas de trabajo **CPU bond** como las de los sistemas de Machine Learning.
|
||||
Pero también puedes aprovechar los beneficios del paralelismo y el multiprocesamiento (tener múltiples procesos ejecutándose en paralelo) para cargas de trabajo **CPU bound** como las de los sistemas de Machine Learning.
|
||||
|
||||
Eso, más el simple hecho de que Python es el lenguaje principal para **Data Science**, Machine Learning y especialmente Deep Learning, hacen de FastAPI una muy buena combinación para las API y aplicaciones web de Data Science / Machine Learning (entre muchas otras).
|
||||
|
||||
|
||||
@@ -433,7 +433,6 @@ Para entender más al respecto revisa la sección <a href="https://fastapi.tiang
|
||||
|
||||
Usadas por Pydantic:
|
||||
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - para <abbr title="convertir el string que viene de un HTTP request a datos de Python">"parsing"</abbr> de JSON más rápido.
|
||||
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - para validación de emails.
|
||||
|
||||
Usados por Starlette:
|
||||
|
||||
@@ -181,7 +181,7 @@ $ uvicorn main:my_awesome_api --reload
|
||||
|
||||
</div>
|
||||
|
||||
### Paso 3: crea un *operación de path*
|
||||
### Paso 3: crea una *operación de path*
|
||||
|
||||
#### Path
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ nav:
|
||||
- Languages:
|
||||
- en: /
|
||||
- az: /az/
|
||||
- cs: /cs/
|
||||
- de: /de/
|
||||
- em: /em/
|
||||
- es: /es/
|
||||
@@ -51,6 +52,7 @@ nav:
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- lo: /lo/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
@@ -114,6 +116,8 @@ extra:
|
||||
name: en - English
|
||||
- link: /az/
|
||||
name: az
|
||||
- link: /cs/
|
||||
name: cs
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /em/
|
||||
@@ -136,6 +140,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /lo/
|
||||
name: lo - ພາສາລາວ
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
|
||||
@@ -436,7 +436,6 @@ item: Item
|
||||
|
||||
استفاده شده توسط Pydantic:
|
||||
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - برای <abbr title="تبدیل دادههای موجود در درخواستهای HTTP به داده پایتونی">"تجزیه (parse)"</abbr> سریعتر JSON .
|
||||
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - برای اعتبارسنجی آدرسهای ایمیل.
|
||||
|
||||
استفاده شده توسط Starlette:
|
||||
|
||||
@@ -40,6 +40,7 @@ nav:
|
||||
- Languages:
|
||||
- en: /
|
||||
- az: /az/
|
||||
- cs: /cs/
|
||||
- de: /de/
|
||||
- em: /em/
|
||||
- es: /es/
|
||||
@@ -51,6 +52,7 @@ nav:
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- lo: /lo/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
@@ -104,6 +106,8 @@ extra:
|
||||
name: en - English
|
||||
- link: /az/
|
||||
name: az
|
||||
- link: /cs/
|
||||
name: cs
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /em/
|
||||
@@ -126,6 +130,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /lo/
|
||||
name: lo - ພາສາລາວ
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
|
||||
63
docs/fr/docs/advanced/response-directly.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Renvoyer directement une réponse
|
||||
|
||||
Lorsque vous créez une *opération de chemins* **FastAPI**, vous pouvez normalement retourner n'importe quelle donnée : un `dict`, une `list`, un modèle Pydantic, un modèle de base de données, etc.
|
||||
|
||||
Par défaut, **FastAPI** convertirait automatiquement cette valeur de retour en JSON en utilisant le `jsonable_encoder` expliqué dans [JSON Compatible Encoder](../tutorial/encoder.md){.internal-link target=_blank}.
|
||||
|
||||
Ensuite, en arrière-plan, il mettra ces données JSON-compatible (par exemple un `dict`) à l'intérieur d'un `JSONResponse` qui sera utilisé pour envoyer la réponse au client.
|
||||
|
||||
Mais vous pouvez retourner une `JSONResponse` directement à partir de vos *opérations de chemin*.
|
||||
|
||||
Cela peut être utile, par exemple, pour retourner des en-têtes personnalisés ou des cookies.
|
||||
|
||||
## Renvoyer une `Response`
|
||||
|
||||
En fait, vous pouvez retourner n'importe quelle `Response` ou n'importe quelle sous-classe de celle-ci.
|
||||
|
||||
!!! Note
|
||||
`JSONResponse` est elle-même une sous-classe de `Response`.
|
||||
|
||||
Et quand vous retournez une `Response`, **FastAPI** la transmet directement.
|
||||
|
||||
Elle ne fera aucune conversion de données avec les modèles Pydantic, elle ne convertira pas le contenu en un type quelconque.
|
||||
|
||||
Cela vous donne beaucoup de flexibilité. Vous pouvez retourner n'importe quel type de données, surcharger n'importe quelle déclaration ou validation de données.
|
||||
|
||||
## Utiliser le `jsonable_encoder` dans une `Response`
|
||||
|
||||
Parce que **FastAPI** n'apporte aucune modification à une `Response` que vous retournez, vous devez vous assurer que son contenu est prêt à être utilisé (sérialisable).
|
||||
|
||||
Par exemple, vous ne pouvez pas mettre un modèle Pydantic dans une `JSONResponse` sans d'abord le convertir en un `dict` avec tous les types de données (comme `datetime`, `UUID`, etc.) convertis en types compatibles avec JSON.
|
||||
|
||||
Pour ces cas, vous pouvez spécifier un appel à `jsonable_encoder` pour convertir vos données avant de les passer à une réponse :
|
||||
|
||||
```Python hl_lines="6-7 21-22"
|
||||
{!../../../docs_src/response_directly/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! note "Détails techniques"
|
||||
Vous pouvez aussi utiliser `from starlette.responses import JSONResponse`.
|
||||
|
||||
**FastAPI** fournit le même objet `starlette.responses` que `fastapi.responses` juste par commodité pour le développeur. Mais la plupart des réponses disponibles proviennent directement de Starlette.
|
||||
|
||||
## Renvoyer une `Response` personnalisée
|
||||
|
||||
L'exemple ci-dessus montre toutes les parties dont vous avez besoin, mais il n'est pas encore très utile, car vous auriez pu retourner l'`item` directement, et **FastAPI** l'aurait mis dans une `JSONResponse` pour vous, en le convertissant en `dict`, etc. Tout cela par défaut.
|
||||
|
||||
Maintenant, voyons comment vous pourriez utiliser cela pour retourner une réponse personnalisée.
|
||||
|
||||
Disons que vous voulez retourner une réponse <a href="https://en.wikipedia.org/wiki/XML" class="external-link" target="_blank">XML</a>.
|
||||
|
||||
Vous pouvez mettre votre contenu XML dans une chaîne de caractères, la placer dans une `Response`, et la retourner :
|
||||
|
||||
```Python hl_lines="1 18"
|
||||
{!../../../docs_src/response_directly/tutorial002.py!}
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
Lorsque vous renvoyez une `Response` directement, ses données ne sont pas validées, converties (sérialisées), ni documentées automatiquement.
|
||||
|
||||
Mais vous pouvez toujours les documenter comme décrit dans [Additional Responses in OpenAPI](additional-responses.md){.internal-link target=_blank}.
|
||||
|
||||
Vous pouvez voir dans les sections suivantes comment utiliser/déclarer ces `Response`s personnalisées tout en conservant la conversion automatique des données, la documentation, etc.
|
||||
@@ -445,7 +445,6 @@ Pour en savoir plus, consultez la section <a href="https://fastapi.tiangolo.com/
|
||||
|
||||
Utilisées par Pydantic:
|
||||
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - pour un <abbr title="convertit la chaine de caractère d'une requête HTTP en donnée Python">"décodage" <abbr title="JavaScript Object Notation">JSON</abbr></abbr> plus rapide.
|
||||
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - pour la validation des adresses email.
|
||||
|
||||
Utilisées par Starlette :
|
||||
|
||||
@@ -40,6 +40,7 @@ nav:
|
||||
- Languages:
|
||||
- en: /
|
||||
- az: /az/
|
||||
- cs: /cs/
|
||||
- de: /de/
|
||||
- em: /em/
|
||||
- es: /es/
|
||||
@@ -51,6 +52,7 @@ nav:
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- lo: /lo/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
@@ -75,6 +77,7 @@ nav:
|
||||
- advanced/index.md
|
||||
- advanced/path-operation-advanced-configuration.md
|
||||
- advanced/additional-status-codes.md
|
||||
- advanced/response-directly.md
|
||||
- advanced/additional-responses.md
|
||||
- async.md
|
||||
- Déploiement:
|
||||
@@ -132,6 +135,8 @@ extra:
|
||||
name: en - English
|
||||
- link: /az/
|
||||
name: az
|
||||
- link: /cs/
|
||||
name: cs
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /em/
|
||||
@@ -154,6 +159,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /lo/
|
||||
name: lo - ພາສາລາວ
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
|
||||
@@ -440,7 +440,6 @@ item: Item
|
||||
|
||||
בשימוש Pydantic:
|
||||
|
||||
- <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - <abbr title="המרת המחרוזת שמגיעה מבקשת HTTP למידע פייתון">"פרסור"</abbr> JSON.
|
||||
- <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - לאימות כתובות אימייל.
|
||||
|
||||
בשימוש Starlette:
|
||||
|
||||
@@ -40,6 +40,7 @@ nav:
|
||||
- Languages:
|
||||
- en: /
|
||||
- az: /az/
|
||||
- cs: /cs/
|
||||
- de: /de/
|
||||
- em: /em/
|
||||
- es: /es/
|
||||
@@ -51,6 +52,7 @@ nav:
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- lo: /lo/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
@@ -104,6 +106,8 @@ extra:
|
||||
name: en - English
|
||||
- link: /az/
|
||||
name: az
|
||||
- link: /cs/
|
||||
name: cs
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /em/
|
||||
@@ -126,6 +130,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /lo/
|
||||
name: lo - ພາສາລາວ
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
|
||||
@@ -40,6 +40,7 @@ nav:
|
||||
- Languages:
|
||||
- en: /
|
||||
- az: /az/
|
||||
- cs: /cs/
|
||||
- de: /de/
|
||||
- em: /em/
|
||||
- es: /es/
|
||||
@@ -51,6 +52,7 @@ nav:
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- lo: /lo/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
@@ -104,6 +106,8 @@ extra:
|
||||
name: en - English
|
||||
- link: /az/
|
||||
name: az
|
||||
- link: /cs/
|
||||
name: cs
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /em/
|
||||
@@ -126,6 +130,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /lo/
|
||||
name: lo - ພາສາລາວ
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
|
||||
@@ -441,7 +441,6 @@ To understand more about it, see the section <a href="https://fastapi.tiangolo.c
|
||||
|
||||
Used by Pydantic:
|
||||
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - for faster JSON <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>.
|
||||
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - for email validation.
|
||||
|
||||
Used by Starlette:
|
||||
|
||||
@@ -10,9 +10,9 @@ Sehingga kamu dapat kembali lagi dan mencari apa yang kamu butuhkan dengan tepat
|
||||
|
||||
## Jalankan kode
|
||||
|
||||
Semua blok-blok kode dapat dicopy dan digunakan langsung (Mereka semua sebenarnya adalah file python yang sudah teruji).
|
||||
Semua blok-blok kode dapat disalin dan digunakan langsung (Mereka semua sebenarnya adalah file python yang sudah teruji).
|
||||
|
||||
Untuk menjalankan setiap contoh, copy kode ke file `main.py`, dan jalankan `uvicorn` dengan:
|
||||
Untuk menjalankan setiap contoh, salin kode ke file `main.py`, dan jalankan `uvicorn` dengan:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
@@ -28,7 +28,7 @@ $ uvicorn main:app --reload
|
||||
|
||||
</div>
|
||||
|
||||
**SANGAT disarankan** agar kamu menulis atau meng-copy kode, meng-editnya dan menjalankannya secara lokal.
|
||||
**SANGAT disarankan** agar kamu menulis atau menyalin kode, mengubahnya dan menjalankannya secara lokal.
|
||||
|
||||
Dengan menggunakannya di dalam editor, benar-benar memperlihatkan manfaat dari FastAPI, melihat bagaimana sedikitnya kode yang harus kamu tulis, semua pengecekan tipe, pelengkapan otomatis, dll.
|
||||
|
||||
@@ -38,7 +38,7 @@ Dengan menggunakannya di dalam editor, benar-benar memperlihatkan manfaat dari F
|
||||
|
||||
Langkah pertama adalah dengan meng-install FastAPI.
|
||||
|
||||
Untuk tutorial, kamu mungkin hendak meng-instalnya dengan semua pilihan fitur dan dependensinya:
|
||||
Untuk tutorial, kamu mungkin hendak meng-installnya dengan semua pilihan fitur dan dependensinya:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
@@ -53,15 +53,15 @@ $ pip install "fastapi[all]"
|
||||
...yang juga termasuk `uvicorn`, yang dapat kamu gunakan sebagai server yang menjalankan kodemu.
|
||||
|
||||
!!! catatan
|
||||
Kamu juga dapat meng-instalnya bagian demi bagian.
|
||||
Kamu juga dapat meng-installnya bagian demi bagian.
|
||||
|
||||
Hal ini mungkin yang akan kamu lakukan ketika kamu hendak men-deploy aplikasimu ke tahap produksi:
|
||||
Hal ini mungkin yang akan kamu lakukan ketika kamu hendak menyebarkan (men-deploy) aplikasimu ke tahap produksi:
|
||||
|
||||
```
|
||||
pip install fastapi
|
||||
```
|
||||
|
||||
Juga install `uvicorn` untk menjalankan server"
|
||||
Juga install `uvicorn` untuk menjalankan server"
|
||||
|
||||
```
|
||||
pip install "uvicorn[standard]"
|
||||
@@ -77,4 +77,4 @@ Tersedia juga **Pedoman Pengguna Lanjutan** yang dapat kamu baca nanti setelah *
|
||||
|
||||
Tetapi kamu harus membaca terlebih dahulu **Tutorial - Pedoman Pengguna** (apa yang sedang kamu baca sekarang).
|
||||
|
||||
Hal ini didesain sehingga kamu dapat membangun aplikasi lengkap dengan hanya **Tutorial - Pedoman Pengguna**, dan kemudian mengembangkannya ke banyak cara yang berbeda, tergantung dari kebutuhanmu, menggunakan beberapa ide-ide tambahan dari **Pedoman Pengguna Lanjutan**.
|
||||
Hal ini dirancang supaya kamu dapat membangun aplikasi lengkap dengan hanya **Tutorial - Pedoman Pengguna**, dan kemudian mengembangkannya ke banyak cara yang berbeda, tergantung dari kebutuhanmu, menggunakan beberapa ide-ide tambahan dari **Pedoman Pengguna Lanjutan**.
|
||||
|
||||
@@ -40,6 +40,7 @@ nav:
|
||||
- Languages:
|
||||
- en: /
|
||||
- az: /az/
|
||||
- cs: /cs/
|
||||
- de: /de/
|
||||
- em: /em/
|
||||
- es: /es/
|
||||
@@ -51,6 +52,7 @@ nav:
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- lo: /lo/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
@@ -104,6 +106,8 @@ extra:
|
||||
name: en - English
|
||||
- link: /az/
|
||||
name: az
|
||||
- link: /cs/
|
||||
name: cs
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /em/
|
||||
@@ -126,6 +130,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /lo/
|
||||
name: lo - ພາສາລາວ
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
|
||||
@@ -438,7 +438,6 @@ To understand more about it, see the section <a href="https://fastapi.tiangolo.c
|
||||
|
||||
Used by Pydantic:
|
||||
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - for faster JSON <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>.
|
||||
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - for email validation.
|
||||
|
||||
Used by Starlette:
|
||||
|
||||
@@ -40,6 +40,7 @@ nav:
|
||||
- Languages:
|
||||
- en: /
|
||||
- az: /az/
|
||||
- cs: /cs/
|
||||
- de: /de/
|
||||
- em: /em/
|
||||
- es: /es/
|
||||
@@ -51,6 +52,7 @@ nav:
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- lo: /lo/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
@@ -104,6 +106,8 @@ extra:
|
||||
name: en - English
|
||||
- link: /az/
|
||||
name: az
|
||||
- link: /cs/
|
||||
name: cs
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /em/
|
||||
@@ -126,6 +130,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /lo/
|
||||
name: lo - ພາສາລາວ
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
|
||||
@@ -97,7 +97,7 @@ $ python -m venv env
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install -e ."[dev,doc,test]"
|
||||
$ pip install -r requirements.txt
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
@@ -431,7 +431,6 @@ item: Item
|
||||
|
||||
Pydantic によって使用されるもの:
|
||||
|
||||
- <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - より速い JSON への<abbr title="converting the string that comes from an HTTP request into Python data">"変換"</abbr>.
|
||||
- <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - E メールの検証
|
||||
|
||||
Starlette によって使用されるもの:
|
||||
|
||||
@@ -40,6 +40,7 @@ nav:
|
||||
- Languages:
|
||||
- en: /
|
||||
- az: /az/
|
||||
- cs: /cs/
|
||||
- de: /de/
|
||||
- em: /em/
|
||||
- es: /es/
|
||||
@@ -51,6 +52,7 @@ nav:
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- lo: /lo/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
@@ -148,6 +150,8 @@ extra:
|
||||
name: en - English
|
||||
- link: /az/
|
||||
name: az
|
||||
- link: /cs/
|
||||
name: cs
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /em/
|
||||
@@ -170,6 +174,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /lo/
|
||||
name: lo - ພາສາລາວ
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
|
||||
@@ -437,7 +437,6 @@ item: Item
|
||||
|
||||
Pydantic이 사용하는:
|
||||
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - 더 빠른 JSON <abbr title="HTTP 요청에서 파이썬 데이터로 가는 문자열 변환">"파싱"</abbr>.
|
||||
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - 이메일 유효성 검사.
|
||||
|
||||
Starlette이 사용하는:
|
||||
|
||||
@@ -40,6 +40,7 @@ nav:
|
||||
- Languages:
|
||||
- en: /
|
||||
- az: /az/
|
||||
- cs: /cs/
|
||||
- de: /de/
|
||||
- em: /em/
|
||||
- es: /es/
|
||||
@@ -51,6 +52,7 @@ nav:
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- lo: /lo/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
@@ -118,6 +120,8 @@ extra:
|
||||
name: en - English
|
||||
- link: /az/
|
||||
name: az
|
||||
- link: /cs/
|
||||
name: cs
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /em/
|
||||
@@ -140,6 +144,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /lo/
|
||||
name: lo - ພາສາລາວ
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
|
||||
469
docs/lo/docs/index.md
Normal file
@@ -0,0 +1,469 @@
|
||||
<p align="center">
|
||||
<a href="https://fastapi.tiangolo.com"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" alt="FastAPI"></a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<em>FastAPI framework, high performance, easy to learn, fast to code, ready for production</em>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://github.com/tiangolo/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
|
||||
<img src="https://github.com/tiangolo/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
|
||||
</a>
|
||||
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/tiangolo/fastapi" target="_blank">
|
||||
<img src="https://coverage-badge.samuelcolvin.workers.dev/tiangolo/fastapi.svg" alt="Coverage">
|
||||
</a>
|
||||
<a href="https://pypi.org/project/fastapi" target="_blank">
|
||||
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Package version">
|
||||
</a>
|
||||
<a href="https://pypi.org/project/fastapi" target="_blank">
|
||||
<img src="https://img.shields.io/pypi/pyversions/fastapi.svg?color=%2334D058" alt="Supported Python versions">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
**Documentation**: <a href="https://fastapi.tiangolo.com" target="_blank">https://fastapi.tiangolo.com</a>
|
||||
|
||||
**Source Code**: <a href="https://github.com/tiangolo/fastapi" target="_blank">https://github.com/tiangolo/fastapi</a>
|
||||
|
||||
---
|
||||
|
||||
FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.7+ based on standard Python type hints.
|
||||
|
||||
The key features are:
|
||||
|
||||
* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
|
||||
* **Fast to code**: Increase the speed to develop features by about 200% to 300%. *
|
||||
* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. *
|
||||
* **Intuitive**: Great editor support. <abbr title="also known as auto-complete, autocompletion, IntelliSense">Completion</abbr> everywhere. Less time debugging.
|
||||
* **Easy**: Designed to be easy to use and learn. Less time reading docs.
|
||||
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
|
||||
* **Robust**: Get production-ready code. With automatic interactive documentation.
|
||||
* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (previously known as Swagger) and <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
|
||||
|
||||
<small>* estimation based on tests on an internal development team, building production applications.</small>
|
||||
|
||||
## Sponsors
|
||||
|
||||
<!-- sponsors -->
|
||||
|
||||
{% if sponsors %}
|
||||
{% for sponsor in sponsors.gold -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
{% endfor -%}
|
||||
{%- for sponsor in sponsors.silver -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
<!-- /sponsors -->
|
||||
|
||||
<a href="https://fastapi.tiangolo.com/fastapi-people/#sponsors" class="external-link" target="_blank">Other sponsors</a>
|
||||
|
||||
## Opinions
|
||||
|
||||
"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/tiangolo/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_**Netflix** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Kevin Glisson, Marc Vilanova, Forest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_I’m over the moon excited about **FastAPI**. It’s so fun!_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a> podcast host</strong> <a href="https://twitter.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]_"
|
||||
|
||||
"_We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> founders - <a href="https://spacy.io" target="_blank">spaCy</a> creators</strong> <a href="https://twitter.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://twitter.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_If anyone is looking to build a production Python API, I would highly recommend **FastAPI**. It is **beautifully designed**, **simple to use** and **highly scalable**, it has become a **key component** in our API first development strategy and is driving many automations and services such as our Virtual TAC Engineer._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
## **Typer**, the FastAPI of CLIs
|
||||
|
||||
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
|
||||
|
||||
If you are building a <abbr title="Command Line Interface">CLI</abbr> app to be used in the terminal instead of a web API, check out <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>.
|
||||
|
||||
**Typer** is FastAPI's little sibling. And it's intended to be the **FastAPI of CLIs**. ⌨️ 🚀
|
||||
|
||||
## Requirements
|
||||
|
||||
Python 3.7+
|
||||
|
||||
FastAPI stands on the shoulders of giants:
|
||||
|
||||
* <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> for the web parts.
|
||||
* <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> for the data parts.
|
||||
|
||||
## Installation
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install fastapi
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
You will also need an ASGI server, for production such as <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> or <a href="https://github.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>.
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "uvicorn[standard]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## Example
|
||||
|
||||
### Create it
|
||||
|
||||
* Create a file `main.py` with:
|
||||
|
||||
```Python
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/")
|
||||
def read_root():
|
||||
return {"Hello": "World"}
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
<details markdown="1">
|
||||
<summary>Or use <code>async def</code>...</summary>
|
||||
|
||||
If your code uses `async` / `await`, use `async def`:
|
||||
|
||||
```Python hl_lines="9 14"
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/")
|
||||
async def read_root():
|
||||
return {"Hello": "World"}
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
async def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
**Note**:
|
||||
|
||||
If you don't know, check the _"In a hurry?"_ section about <a href="https://fastapi.tiangolo.com/async/#in-a-hurry" target="_blank">`async` and `await` in the docs</a>.
|
||||
|
||||
</details>
|
||||
|
||||
### Run it
|
||||
|
||||
Run the server with:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --reload
|
||||
|
||||
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
INFO: Started reloader process [28720]
|
||||
INFO: Started server process [28722]
|
||||
INFO: Waiting for application startup.
|
||||
INFO: Application startup complete.
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
<details markdown="1">
|
||||
<summary>About the command <code>uvicorn main:app --reload</code>...</summary>
|
||||
|
||||
The command `uvicorn main:app` refers to:
|
||||
|
||||
* `main`: the file `main.py` (the Python "module").
|
||||
* `app`: the object created inside of `main.py` with the line `app = FastAPI()`.
|
||||
* `--reload`: make the server restart after code changes. Only do this for development.
|
||||
|
||||
</details>
|
||||
|
||||
### Check it
|
||||
|
||||
Open your browser at <a href="http://127.0.0.1:8000/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1:8000/items/5?q=somequery</a>.
|
||||
|
||||
You will see the JSON response as:
|
||||
|
||||
```JSON
|
||||
{"item_id": 5, "q": "somequery"}
|
||||
```
|
||||
|
||||
You already created an API that:
|
||||
|
||||
* Receives HTTP requests in the _paths_ `/` and `/items/{item_id}`.
|
||||
* Both _paths_ take `GET` <em>operations</em> (also known as HTTP _methods_).
|
||||
* The _path_ `/items/{item_id}` has a _path parameter_ `item_id` that should be an `int`.
|
||||
* The _path_ `/items/{item_id}` has an optional `str` _query parameter_ `q`.
|
||||
|
||||
### Interactive API docs
|
||||
|
||||
Now go to <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||
|
||||
You will see the automatic interactive API documentation (provided by <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
|
||||
|
||||

|
||||
|
||||
### Alternative API docs
|
||||
|
||||
And now, go to <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
|
||||
|
||||
You will see the alternative automatic documentation (provided by <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>):
|
||||
|
||||

|
||||
|
||||
## Example upgrade
|
||||
|
||||
Now modify the file `main.py` to receive a body from a `PUT` request.
|
||||
|
||||
Declare the body using standard Python types, thanks to Pydantic.
|
||||
|
||||
```Python hl_lines="4 9-12 25-27"
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
from pydantic import BaseModel
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
class Item(BaseModel):
|
||||
name: str
|
||||
price: float
|
||||
is_offer: Union[bool, None] = None
|
||||
|
||||
|
||||
@app.get("/")
|
||||
def read_root():
|
||||
return {"Hello": "World"}
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
|
||||
|
||||
@app.put("/items/{item_id}")
|
||||
def update_item(item_id: int, item: Item):
|
||||
return {"item_name": item.name, "item_id": item_id}
|
||||
```
|
||||
|
||||
The server should reload automatically (because you added `--reload` to the `uvicorn` command above).
|
||||
|
||||
### Interactive API docs upgrade
|
||||
|
||||
Now go to <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||
|
||||
* The interactive API documentation will be automatically updated, including the new body:
|
||||
|
||||

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

|
||||
|
||||
* Then click on the "Execute" button, the user interface will communicate with your API, send the parameters, get the results and show them on the screen:
|
||||
|
||||

|
||||
|
||||
### Alternative API docs upgrade
|
||||
|
||||
And now, go to <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
|
||||
|
||||
* The alternative documentation will also reflect the new query parameter and body:
|
||||
|
||||

|
||||
|
||||
### Recap
|
||||
|
||||
In summary, you declare **once** the types of parameters, body, etc. as function parameters.
|
||||
|
||||
You do that with standard modern Python types.
|
||||
|
||||
You don't have to learn a new syntax, the methods or classes of a specific library, etc.
|
||||
|
||||
Just standard **Python 3.7+**.
|
||||
|
||||
For example, for an `int`:
|
||||
|
||||
```Python
|
||||
item_id: int
|
||||
```
|
||||
|
||||
or for a more complex `Item` model:
|
||||
|
||||
```Python
|
||||
item: Item
|
||||
```
|
||||
|
||||
...and with that single declaration you get:
|
||||
|
||||
* Editor support, including:
|
||||
* Completion.
|
||||
* Type checks.
|
||||
* Validation of data:
|
||||
* Automatic and clear errors when the data is invalid.
|
||||
* Validation even for deeply nested JSON objects.
|
||||
* <abbr title="also known as: serialization, parsing, marshalling">Conversion</abbr> of input data: coming from the network to Python data and types. Reading from:
|
||||
* JSON.
|
||||
* Path parameters.
|
||||
* Query parameters.
|
||||
* Cookies.
|
||||
* Headers.
|
||||
* Forms.
|
||||
* Files.
|
||||
* <abbr title="also known as: serialization, parsing, marshalling">Conversion</abbr> of output data: converting from Python data and types to network data (as JSON):
|
||||
* Convert Python types (`str`, `int`, `float`, `bool`, `list`, etc).
|
||||
* `datetime` objects.
|
||||
* `UUID` objects.
|
||||
* Database models.
|
||||
* ...and many more.
|
||||
* Automatic interactive API documentation, including 2 alternative user interfaces:
|
||||
* Swagger UI.
|
||||
* ReDoc.
|
||||
|
||||
---
|
||||
|
||||
Coming back to the previous code example, **FastAPI** will:
|
||||
|
||||
* Validate that there is an `item_id` in the path for `GET` and `PUT` requests.
|
||||
* Validate that the `item_id` is of type `int` for `GET` and `PUT` requests.
|
||||
* If it is not, the client will see a useful, clear error.
|
||||
* Check if there is an optional query parameter named `q` (as in `http://127.0.0.1:8000/items/foo?q=somequery`) for `GET` requests.
|
||||
* As the `q` parameter is declared with `= None`, it is optional.
|
||||
* Without the `None` it would be required (as is the body in the case with `PUT`).
|
||||
* For `PUT` requests to `/items/{item_id}`, Read the body as JSON:
|
||||
* Check that it has a required attribute `name` that should be a `str`.
|
||||
* Check that it has a required attribute `price` that has to be a `float`.
|
||||
* Check that it has an optional attribute `is_offer`, that should be a `bool`, if present.
|
||||
* All this would also work for deeply nested JSON objects.
|
||||
* Convert from and to JSON automatically.
|
||||
* Document everything with OpenAPI, that can be used by:
|
||||
* Interactive documentation systems.
|
||||
* Automatic client code generation systems, for many languages.
|
||||
* Provide 2 interactive documentation web interfaces directly.
|
||||
|
||||
---
|
||||
|
||||
We just scratched the surface, but you already get the idea of how it all works.
|
||||
|
||||
Try changing the line with:
|
||||
|
||||
```Python
|
||||
return {"item_name": item.name, "item_id": item_id}
|
||||
```
|
||||
|
||||
...from:
|
||||
|
||||
```Python
|
||||
... "item_name": item.name ...
|
||||
```
|
||||
|
||||
...to:
|
||||
|
||||
```Python
|
||||
... "item_price": item.price ...
|
||||
```
|
||||
|
||||
...and see how your editor will auto-complete the attributes and know their types:
|
||||
|
||||

|
||||
|
||||
For a more complete example including more features, see the <a href="https://fastapi.tiangolo.com/tutorial/">Tutorial - User Guide</a>.
|
||||
|
||||
**Spoiler alert**: the tutorial - user guide includes:
|
||||
|
||||
* Declaration of **parameters** from other different places as: **headers**, **cookies**, **form fields** and **files**.
|
||||
* How to set **validation constraints** as `maximum_length` or `regex`.
|
||||
* A very powerful and easy to use **<abbr title="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** system.
|
||||
* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth.
|
||||
* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic).
|
||||
* **GraphQL** integration with <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> and other libraries.
|
||||
* Many extra features (thanks to Starlette) as:
|
||||
* **WebSockets**
|
||||
* extremely easy tests based on HTTPX and `pytest`
|
||||
* **CORS**
|
||||
* **Cookie Sessions**
|
||||
* ...and more.
|
||||
|
||||
## Performance
|
||||
|
||||
Independent TechEmpower benchmarks show **FastAPI** applications running under Uvicorn as <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">one of the fastest Python frameworks available</a>, only below Starlette and Uvicorn themselves (used internally by FastAPI). (*)
|
||||
|
||||
To understand more about it, see the section <a href="https://fastapi.tiangolo.com/benchmarks/" class="internal-link" target="_blank">Benchmarks</a>.
|
||||
|
||||
## Optional Dependencies
|
||||
|
||||
Used by Pydantic:
|
||||
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - for faster JSON <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>.
|
||||
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - for email validation.
|
||||
|
||||
Used by Starlette:
|
||||
|
||||
* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - Required if you want to use the `TestClient`.
|
||||
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
|
||||
* <a href="https://andrew-d.github.io/python-multipart/" target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`.
|
||||
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Required for `SessionMiddleware` support.
|
||||
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Required for Starlette's `SchemaGenerator` support (you probably don't need it with FastAPI).
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Required if you want to use `UJSONResponse`.
|
||||
|
||||
Used by FastAPI / Starlette:
|
||||
|
||||
* <a href="https://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - for the server that loads and serves your application.
|
||||
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - Required if you want to use `ORJSONResponse`.
|
||||
|
||||
You can install all of these with `pip install "fastapi[all]"`.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the terms of the MIT license.
|
||||
157
docs/lo/mkdocs.yml
Normal file
@@ -0,0 +1,157 @@
|
||||
site_name: FastAPI
|
||||
site_description: FastAPI framework, high performance, easy to learn, fast to code, ready for production
|
||||
site_url: https://fastapi.tiangolo.com/lo/
|
||||
theme:
|
||||
name: material
|
||||
custom_dir: overrides
|
||||
palette:
|
||||
- media: '(prefers-color-scheme: light)'
|
||||
scheme: default
|
||||
primary: teal
|
||||
accent: amber
|
||||
toggle:
|
||||
icon: material/lightbulb
|
||||
name: Switch to light mode
|
||||
- media: '(prefers-color-scheme: dark)'
|
||||
scheme: slate
|
||||
primary: teal
|
||||
accent: amber
|
||||
toggle:
|
||||
icon: material/lightbulb-outline
|
||||
name: Switch to dark mode
|
||||
features:
|
||||
- search.suggest
|
||||
- search.highlight
|
||||
- content.tabs.link
|
||||
icon:
|
||||
repo: fontawesome/brands/github-alt
|
||||
logo: https://fastapi.tiangolo.com/img/icon-white.svg
|
||||
favicon: https://fastapi.tiangolo.com/img/favicon.png
|
||||
language: en
|
||||
repo_name: tiangolo/fastapi
|
||||
repo_url: https://github.com/tiangolo/fastapi
|
||||
edit_uri: ''
|
||||
plugins:
|
||||
- search
|
||||
- markdownextradata:
|
||||
data: data
|
||||
nav:
|
||||
- FastAPI: index.md
|
||||
- Languages:
|
||||
- en: /
|
||||
- az: /az/
|
||||
- de: /de/
|
||||
- em: /em/
|
||||
- es: /es/
|
||||
- fa: /fa/
|
||||
- fr: /fr/
|
||||
- he: /he/
|
||||
- hy: /hy/
|
||||
- id: /id/
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- lo: /lo/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
- ru: /ru/
|
||||
- sq: /sq/
|
||||
- sv: /sv/
|
||||
- ta: /ta/
|
||||
- tr: /tr/
|
||||
- uk: /uk/
|
||||
- zh: /zh/
|
||||
markdown_extensions:
|
||||
- toc:
|
||||
permalink: true
|
||||
- markdown.extensions.codehilite:
|
||||
guess_lang: false
|
||||
- mdx_include:
|
||||
base_path: docs
|
||||
- admonition
|
||||
- codehilite
|
||||
- extra
|
||||
- pymdownx.superfences:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
- attr_list
|
||||
- md_in_html
|
||||
extra:
|
||||
analytics:
|
||||
provider: google
|
||||
property: G-YNEVN69SC3
|
||||
social:
|
||||
- icon: fontawesome/brands/github-alt
|
||||
link: https://github.com/tiangolo/fastapi
|
||||
- icon: fontawesome/brands/discord
|
||||
link: https://discord.gg/VQjSZaeJmf
|
||||
- icon: fontawesome/brands/twitter
|
||||
link: https://twitter.com/fastapi
|
||||
- icon: fontawesome/brands/linkedin
|
||||
link: https://www.linkedin.com/in/tiangolo
|
||||
- icon: fontawesome/brands/dev
|
||||
link: https://dev.to/tiangolo
|
||||
- icon: fontawesome/brands/medium
|
||||
link: https://medium.com/@tiangolo
|
||||
- icon: fontawesome/solid/globe
|
||||
link: https://tiangolo.com
|
||||
alternate:
|
||||
- link: /
|
||||
name: en - English
|
||||
- link: /az/
|
||||
name: az
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /em/
|
||||
name: 😉
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fa/
|
||||
name: fa
|
||||
- link: /fr/
|
||||
name: fr - français
|
||||
- link: /he/
|
||||
name: he
|
||||
- link: /hy/
|
||||
name: hy
|
||||
- link: /id/
|
||||
name: id
|
||||
- link: /it/
|
||||
name: it - italiano
|
||||
- link: /ja/
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /lo/
|
||||
name: lo - ພາສາລາວ
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
name: pl
|
||||
- link: /pt/
|
||||
name: pt - português
|
||||
- link: /ru/
|
||||
name: ru - русский язык
|
||||
- link: /sq/
|
||||
name: sq - shqip
|
||||
- link: /sv/
|
||||
name: sv - svenska
|
||||
- link: /ta/
|
||||
name: ta - தமிழ்
|
||||
- link: /tr/
|
||||
name: tr - Türkçe
|
||||
- link: /uk/
|
||||
name: uk - українська мова
|
||||
- link: /zh/
|
||||
name: zh - 汉语
|
||||
extra_css:
|
||||
- https://fastapi.tiangolo.com/css/termynal.css
|
||||
- https://fastapi.tiangolo.com/css/custom.css
|
||||
extra_javascript:
|
||||
- https://fastapi.tiangolo.com/js/termynal.js
|
||||
- https://fastapi.tiangolo.com/js/custom.js
|
||||
0
docs/lo/overrides/.gitignore
vendored
Normal file
@@ -444,7 +444,6 @@ To understand more about it, see the section <a href="https://fastapi.tiangolo.c
|
||||
|
||||
Used by Pydantic:
|
||||
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - for faster JSON <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>.
|
||||
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - for email validation.
|
||||
|
||||
Used by Starlette:
|
||||
|
||||
@@ -40,6 +40,7 @@ nav:
|
||||
- Languages:
|
||||
- en: /
|
||||
- az: /az/
|
||||
- cs: /cs/
|
||||
- de: /de/
|
||||
- em: /em/
|
||||
- es: /es/
|
||||
@@ -51,6 +52,7 @@ nav:
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- lo: /lo/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
@@ -104,6 +106,8 @@ extra:
|
||||
name: en - English
|
||||
- link: /az/
|
||||
name: az
|
||||
- link: /cs/
|
||||
name: cs
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /em/
|
||||
@@ -126,6 +130,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /lo/
|
||||
name: lo - ພາສາລາວ
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
|
||||
200
docs/pl/docs/features.md
Normal file
@@ -0,0 +1,200 @@
|
||||
# Cechy
|
||||
|
||||
## Cechy FastAPI
|
||||
|
||||
**FastAPI** zapewnia Ci następujące korzyści:
|
||||
|
||||
### Oparcie o standardy open
|
||||
|
||||
* <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a> do tworzenia API, w tym deklaracji <abbr title="znane również jako: paths, endpoints, routes">ścieżek</abbr> <abbr title="znane również jako metody HTTP, takie jak POST, GET, PUT, DELETE">operacji</abbr>, parametrów, <abbr title="po angielsku: body requests">ciał zapytań</abbr>, bezpieczeństwa, itp.
|
||||
* Automatyczna dokumentacja modelu danych za pomocą <a href="https://json-schema.org/" class="external-link" target="_blank"><strong>JSON Schema</strong></a> (ponieważ OpenAPI bazuje na JSON Schema).
|
||||
* Zaprojektowane z myślą o zgodności z powyższymi standardami zamiast dodawania ich obsługi po fakcie.
|
||||
* Możliwość automatycznego **generowania kodu klienta** w wielu językach.
|
||||
|
||||
### Automatyczna dokumentacja
|
||||
|
||||
Interaktywna dokumentacja i webowe interfejsy do eksploracji API. Z racji tego, że framework bazuje na OpenAPI, istnieje wiele opcji, z czego 2 są domyślnie dołączone.
|
||||
|
||||
* <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank"><strong>Swagger UI</strong></a>, z interaktywnym interfejsem - odpytuj i testuj swoje API bezpośrednio z przeglądarki.
|
||||
|
||||

|
||||
|
||||
* Alternatywna dokumentacja API z <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank"><strong>ReDoc</strong></a>.
|
||||
|
||||

|
||||
|
||||
### Nowoczesny Python
|
||||
|
||||
Wszystko opiera się na standardowych deklaracjach typu **Python 3.6** (dzięki Pydantic). Brak nowej składni do uczenia. Po prostu standardowy, współczesny Python.
|
||||
|
||||
Jeśli potrzebujesz szybkiego przypomnienia jak używać deklaracji typów w Pythonie (nawet jeśli nie używasz FastAPI), sprawdź krótki samouczek: [Python Types](python-types.md){.internal-link target=_blank}.
|
||||
|
||||
Wystarczy, że napiszesz standardowe deklaracje typów Pythona:
|
||||
|
||||
```Python
|
||||
from datetime import date
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
# Zadeklaruj parametr jako str
|
||||
# i uzyskaj wsparcie edytora wewnątrz funkcji
|
||||
def main(user_id: str):
|
||||
return user_id
|
||||
|
||||
|
||||
# Model Pydantic
|
||||
class User(BaseModel):
|
||||
id: int
|
||||
name: str
|
||||
joined: date
|
||||
```
|
||||
|
||||
A one będą mogły zostać później użyte w następujący sposób:
|
||||
|
||||
```Python
|
||||
my_user: User = User(id=3, name="John Doe", joined="2018-07-19")
|
||||
|
||||
second_user_data = {
|
||||
"id": 4,
|
||||
"name": "Mary",
|
||||
"joined": "2018-11-30",
|
||||
}
|
||||
|
||||
my_second_user: User = User(**second_user_data)
|
||||
```
|
||||
|
||||
!!! info
|
||||
`**second_user_data` oznacza:
|
||||
|
||||
Przekaż klucze i wartości słownika `second_user_data` bezpośrednio jako argumenty klucz-wartość, co jest równoznaczne z: `User(id=4, name="Mary", joined="2018-11-30")`
|
||||
|
||||
### Wsparcie edytora
|
||||
|
||||
Cały framework został zaprojektowany tak, aby był łatwy i intuicyjny w użyciu. Wszystkie pomysły zostały przetestowane na wielu edytorach jeszcze przed rozpoczęciem procesu tworzenia, aby zapewnić najlepsze wrażenia programistyczne.
|
||||
|
||||
Ostatnia ankieta <abbr title="coroczna ankieta przeprowadza w środowisku programistów języka Python">Python developer survey</abbr> jasno wskazuje, że <a href="https://www.jetbrains.com/research/python-developers-survey-2017/#tools-and-features" class="external-link" target="_blank">najczęściej używaną funkcjonalnością jest autouzupełnianie w edytorze</a>.
|
||||
|
||||
Cała struktura frameworku **FastAPI** jest na tym oparta. Autouzupełnianie działa wszędzie.
|
||||
|
||||
Rzadko będziesz musiał wracać do dokumentacji.
|
||||
|
||||
Oto, jak twój edytor może Ci pomóc:
|
||||
|
||||
* <a href="https://code.visualstudio.com/" class="external-link" target="_blank">Visual Studio Code</a>:
|
||||
|
||||

|
||||
|
||||
* <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a>:
|
||||
|
||||

|
||||
|
||||
Otrzymasz uzupełnienie nawet w miejscach, w których normalnie uzupełnienia nie ma. Na przykład klucz "price" w treści JSON (który mógł być zagnieżdżony), który pochodzi z zapytania.
|
||||
|
||||
Koniec z wpisywaniem błędnych nazw kluczy, przechodzeniem tam i z powrotem w dokumentacji lub przewijaniem w górę i w dół, aby sprawdzić, czy w końcu użyłeś nazwy `username` czy `user_name`.
|
||||
|
||||
### Zwięzłość
|
||||
|
||||
Wszystko posiada sensowne **domyślne wartości**. Wszędzie znajdziesz opcjonalne konfiguracje. Wszystkie parametry możesz dostroić, aby zrobić to co potrzebujesz do zdefiniowania API.
|
||||
|
||||
Ale domyślnie wszystko **"po prostu działa"**.
|
||||
|
||||
### Walidacja
|
||||
|
||||
* Walidacja większości (lub wszystkich?) **typów danych** Pythona, w tym:
|
||||
* Obiektów JSON (`dict`).
|
||||
* Tablic JSON (`list`) ze zdefiniowanym typem elementów.
|
||||
* Pól tekstowych (`str`) z określeniem minimalnej i maksymalnej długości.
|
||||
* Liczb (`int`, `float`) z wartościami minimalnymi, maksymalnymi, itp.
|
||||
|
||||
* Walidacja bardziej egzotycznych typów danych, takich jak:
|
||||
* URL.
|
||||
* Email.
|
||||
* UUID.
|
||||
* ...i inne.
|
||||
|
||||
Cała walidacja jest obsługiwana przez ugruntowaną i solidną bibliotekę **Pydantic**.
|
||||
|
||||
### Bezpieczeństwo i uwierzytelnianie
|
||||
|
||||
Bezpieczeństwo i uwierzytelnianie jest zintegrowane. Bez żadnych kompromisów z bazami czy modelami danych.
|
||||
|
||||
Wszystkie schematy bezpieczeństwa zdefiniowane w OpenAPI, w tym:
|
||||
|
||||
* Podstawowy protokół HTTP.
|
||||
* **OAuth2** (również z **tokenami JWT**). Sprawdź samouczek [OAuth2 with JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank}.
|
||||
* Klucze API w:
|
||||
* Nagłówkach.
|
||||
* Parametrach zapytań.
|
||||
* Ciasteczkach, itp.
|
||||
|
||||
Plus wszystkie funkcje bezpieczeństwa Starlette (włączając w to **<abbr title="po angielsku: session cookies">ciasteczka sesyjne</abbr>**).
|
||||
|
||||
Wszystko zbudowane jako narzędzia i komponenty wielokrotnego użytku, które można łatwo zintegrować z systemami, magazynami oraz bazami danych - relacyjnymi, NoSQL, itp.
|
||||
|
||||
### Wstrzykiwanie Zależności
|
||||
|
||||
FastAPI zawiera niezwykle łatwy w użyciu, ale niezwykle potężny system <abbr title='Po angielsku: Dependency Injection. Znane również jako "components", "resources", "services", "providers"'><strong>Wstrzykiwania Zależności</strong></abbr>.
|
||||
|
||||
* Nawet zależności mogą mieć zależności, tworząc hierarchię lub **"graf" zależności**.
|
||||
* Wszystko jest **obsługiwane automatycznie** przez framework.
|
||||
* Wszystkie zależności mogą wymagać danych w żądaniach oraz rozszerzać ograniczenia i automatyczną dokumentację **<abbr title="po angielsku: path operations">operacji na ścieżce</abbr>**.
|
||||
* **Automatyczna walidacja** parametrów *operacji na ścieżce* zdefiniowanych w zależnościach.
|
||||
* Obsługa złożonych systemów uwierzytelniania użytkowników, **połączeń z bazami danych**, itp.
|
||||
* Bazy danych, front end, itp. **bez kompromisów**, ale wciąż łatwe do integracji.
|
||||
|
||||
### Nieograniczone "wtyczki"
|
||||
|
||||
Lub ujmując to inaczej - brak potrzeby wtyczek. Importuj i używaj kod, który potrzebujesz.
|
||||
|
||||
Każda integracja została zaprojektowana tak, aby była tak prosta w użyciu (z zależnościami), że możesz utworzyć "wtyczkę" dla swojej aplikacji w 2 liniach kodu, używając tej samej struktury i składni, które są używane w *operacjach na ścieżce*.
|
||||
|
||||
### Testy
|
||||
|
||||
* 100% <abbr title="Ilość kodu, który jest automatycznie testowany">pokrycia kodu testami</abbr>.
|
||||
* 100% <abbr title="Deklaracje typów Python - dzięki nim twój edytor i zewnętrzne narzędzia mogą zapewnić Ci lepsze wsparcie ">adnotacji typów</abbr>.
|
||||
* Używany w aplikacjach produkcyjnych.
|
||||
|
||||
## Cechy Starlette
|
||||
|
||||
**FastAPI** jest w pełni kompatybilny z (oraz bazuje na) <a href="https://www.starlette.io/" class="external-link" target="_blank"><strong>Starlette</strong></a>. Tak więc każdy dodatkowy kod Starlette, który posiadasz, również będzie działał.
|
||||
|
||||
`FastAPI` jest w rzeczywistości podklasą `Starlette`, więc jeśli już znasz lub używasz Starlette, większość funkcji będzie działać w ten sam sposób.
|
||||
|
||||
Dzięki **FastAPI** otrzymujesz wszystkie funkcje **Starlette** (ponieważ FastAPI to po prostu Starlette na sterydach):
|
||||
|
||||
* Bardzo imponująca wydajność. Jest to <a href="https://github.com/encode/starlette#performance" class="external-link" target="_blank">jeden z najszybszych dostępnych frameworków Pythona, na równi z **NodeJS** i **Go**</a>.
|
||||
* Wsparcie dla **WebSocket**.
|
||||
* <abbr title='Zadania wykonywane w tle, bez zatrzymywania żądań, w tym samym procesie. Po angielsku: In-process background tasks'>Zadania w tle</abbr>.
|
||||
* Eventy startup i shutdown.
|
||||
* Klient testowy zbudowany na bazie biblioteki `requests`.
|
||||
* **CORS**, GZip, pliki statyczne, streamy.
|
||||
* Obsługa **sesji i ciasteczek**.
|
||||
* 100% pokrycie testami.
|
||||
* 100% adnotacji typów.
|
||||
|
||||
## Cechy Pydantic
|
||||
|
||||
**FastAPI** jest w pełni kompatybilny z (oraz bazuje na) <a href="https://pydantic-docs.helpmanual.io" class="external-link" target="_blank"><strong>Pydantic</strong></a>. Tak więc każdy dodatkowy kod Pydantic, który posiadasz, również będzie działał.
|
||||
|
||||
Wliczając w to zewnętrzne biblioteki, również oparte o Pydantic, takie jak <abbr title="Mapowanie obiektowo-relacyjne. Po angielsku: Object-Relational Mapper">ORM</abbr>, <abbr title="Object-Document Mapper">ODM</abbr> dla baz danych.
|
||||
|
||||
Oznacza to, że w wielu przypadkach możesz przekazać ten sam obiekt, który otrzymasz z żądania **bezpośrednio do bazy danych**, ponieważ wszystko jest walidowane automatycznie.
|
||||
|
||||
Działa to również w drugą stronę, w wielu przypadkach możesz po prostu przekazać obiekt otrzymany z bazy danych **bezpośrednio do klienta**.
|
||||
|
||||
Dzięki **FastAPI** otrzymujesz wszystkie funkcje **Pydantic** (ponieważ FastAPI bazuje na Pydantic do obsługi wszystkich danych):
|
||||
|
||||
* **Bez prania mózgu**:
|
||||
* Brak nowego mikrojęzyka do definiowania schematu, którego trzeba się nauczyć.
|
||||
* Jeśli znasz adnotacje typów Pythona to wiesz jak używać Pydantic.
|
||||
* Dobrze współpracuje z Twoim **<abbr title='Skrót od "Integrated Development Environment", podobne do edytora kodu'>IDE</abbr>/<abbr title="Program, który sprawdza Twój kod pod kątem błędów">linterem</abbr>/mózgiem**:
|
||||
* Ponieważ struktury danych Pydantic to po prostu instancje klas, które definiujesz; autouzupełnianie, linting, mypy i twoja intuicja powinny działać poprawnie z Twoimi zwalidowanymi danymi.
|
||||
* **Szybkość**:
|
||||
* w <a href="https://pydantic-docs.helpmanual.io/benchmarks/" class="external-link" target="_blank">benchmarkach</a> Pydantic jest szybszy niż wszystkie inne testowane biblioteki.
|
||||
* Walidacja **złożonych struktur**:
|
||||
* Wykorzystanie hierarchicznych modeli Pydantic, Pythonowego modułu `typing` zawierającego `List`, `Dict`, itp.
|
||||
* Walidatory umożliwiają jasne i łatwe definiowanie, sprawdzanie złożonych struktur danych oraz dokumentowanie ich jako JSON Schema.
|
||||
* Możesz mieć głęboko **zagnieżdżone obiekty JSON** i wszystkie je poddać walidacji i adnotować.
|
||||
* **Rozszerzalność**:
|
||||
* Pydantic umożliwia zdefiniowanie niestandardowych typów danych lub rozszerzenie walidacji o metody na modelu, na których użyty jest dekorator walidatora.
|
||||
* 100% pokrycie testami.
|
||||
@@ -435,7 +435,6 @@ Aby dowiedzieć się o tym więcej, zobacz sekcję <a href="https://fastapi.tian
|
||||
|
||||
Używane przez Pydantic:
|
||||
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - dla szybszego <abbr title="przetwarzania stringa który przychodzi z żądaniem HTTP na dane używane przez Pythona">"parsowania"</abbr> danych JSON.
|
||||
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - dla walidacji adresów email.
|
||||
|
||||
Używane przez Starlette:
|
||||
|
||||
@@ -40,6 +40,7 @@ nav:
|
||||
- Languages:
|
||||
- en: /
|
||||
- az: /az/
|
||||
- cs: /cs/
|
||||
- de: /de/
|
||||
- em: /em/
|
||||
- es: /es/
|
||||
@@ -51,6 +52,7 @@ nav:
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- lo: /lo/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
@@ -61,6 +63,7 @@ nav:
|
||||
- tr: /tr/
|
||||
- uk: /uk/
|
||||
- zh: /zh/
|
||||
- features.md
|
||||
- Samouczek:
|
||||
- tutorial/index.md
|
||||
- tutorial/first-steps.md
|
||||
@@ -107,6 +110,8 @@ extra:
|
||||
name: en - English
|
||||
- link: /az/
|
||||
name: az
|
||||
- link: /cs/
|
||||
name: cs
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /em/
|
||||
@@ -129,6 +134,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /lo/
|
||||
name: lo - ພາສາລາວ
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
|
||||
163
docs/pt/docs/advanced/events.md
Normal file
@@ -0,0 +1,163 @@
|
||||
# Eventos de vida útil
|
||||
|
||||
Você pode definir a lógica (código) que poderia ser executada antes da aplicação **inicializar**. Isso significa que esse código será executado **uma vez**, **antes** da aplicação **começar a receber requisições**.
|
||||
|
||||
Do mesmo modo, você pode definir a lógica (código) que será executada quando a aplicação estiver sendo **encerrada**. Nesse caso, este código será executado **uma vez**, **depois** de ter possivelmente tratado **várias requisições**.
|
||||
|
||||
Por conta desse código ser executado antes da aplicação **começar** a receber requisições, e logo após **terminar** de lidar com as requisições, ele cobre toda a **vida útil** (_lifespan_) da aplicação (o termo "vida útil" será importante em um segundo 😉).
|
||||
|
||||
Pode ser muito útil para configurar **recursos** que você precisa usar por toda aplicação, e que são **compartilhados** entre as requisições, e/ou que você precisa **limpar** depois. Por exemplo, o pool de uma conexão com o banco de dados ou carregamento de um modelo compartilhado de aprendizado de máquina (_machine learning_).
|
||||
|
||||
## Caso de uso
|
||||
|
||||
Vamos iniciar com um exemplo de **caso de uso** e então ver como resolvê-lo com isso.
|
||||
|
||||
Vamos imaginar que você tem alguns **modelos de _machine learning_** que deseja usar para lidar com as requisições. 🤖
|
||||
|
||||
Os mesmos modelos são compartilhados entre as requisições, então não é um modelo por requisição, ou um por usuário ou algo parecido.
|
||||
|
||||
Vamos imaginar que o carregamento do modelo pode **demorar bastante tempo**, porque ele tem que ler muitos **dados do disco**. Então você não quer fazer isso a cada requisição.
|
||||
|
||||
Você poderia carregá-lo no nível mais alto do módulo/arquivo, mas isso também poderia significaria **carregar o modelo** mesmo se você estiver executando um simples teste automatizado, então esse teste poderia ser **lento** porque teria que esperar o carregamento do modelo antes de ser capaz de executar uma parte independente do código.
|
||||
|
||||
|
||||
Isso é que nós iremos resolver, vamos carregar o modelo antes das requisições serem manuseadas, mas apenas um pouco antes da aplicação começar a receber requisições, não enquanto o código estiver sendo carregado.
|
||||
|
||||
## Vida útil (_Lifespan_)
|
||||
|
||||
Você pode definir essa lógica de *inicialização* e *encerramento* usando os parâmetros de `lifespan` da aplicação `FastAPI`, e um "gerenciador de contexto" (te mostrarei o que é isso a seguir).
|
||||
|
||||
Vamos iniciar com um exemplo e ver isso detalhadamente.
|
||||
|
||||
Nós criamos uma função assíncrona chamada `lifespan()` com `yield` como este:
|
||||
|
||||
```Python hl_lines="16 19"
|
||||
{!../../../docs_src/events/tutorial003.py!}
|
||||
```
|
||||
|
||||
Aqui nós estamos simulando a *inicialização* custosa do carregamento do modelo colocando a (falsa) função de modelo no dicionário com modelos de _machine learning_ antes do `yield`. Este código será executado **antes** da aplicação **começar a receber requisições**, durante a *inicialização*.
|
||||
|
||||
E então, logo após o `yield`, descarregaremos o modelo. Esse código será executado **após** a aplicação **terminar de lidar com as requisições**, pouco antes do *encerramento*. Isso poderia, por exemplo, liberar recursos como memória ou GPU.
|
||||
|
||||
!!! tip "Dica"
|
||||
O `shutdown` aconteceria quando você estivesse **encerrando** a aplicação.
|
||||
|
||||
Talvez você precise inicializar uma nova versão, ou apenas cansou de executá-la. 🤷
|
||||
|
||||
### Função _lifespan_
|
||||
|
||||
A primeira coisa a notar, é que estamos definindo uma função assíncrona com `yield`. Isso é muito semelhante à Dependências com `yield`.
|
||||
|
||||
```Python hl_lines="14-19"
|
||||
{!../../../docs_src/events/tutorial003.py!}
|
||||
```
|
||||
|
||||
A primeira parte da função, antes do `yield`, será executada **antes** da aplicação inicializar.
|
||||
|
||||
E a parte posterior do `yield` irá executar **após** a aplicação ser encerrada.
|
||||
|
||||
### Gerenciador de Contexto Assíncrono
|
||||
|
||||
Se você verificar, a função está decorada com um `@asynccontextmanager`.
|
||||
|
||||
Que converte a função em algo chamado de "**Gerenciador de Contexto Assíncrono**".
|
||||
|
||||
```Python hl_lines="1 13"
|
||||
{!../../../docs_src/events/tutorial003.py!}
|
||||
```
|
||||
|
||||
Um **gerenciador de contexto** em Python é algo que você pode usar em uma declaração `with`, por exemplo, `open()` pode ser usado como um gerenciador de contexto:
|
||||
|
||||
```Python
|
||||
with open("file.txt") as file:
|
||||
file.read()
|
||||
```
|
||||
|
||||
Nas versões mais recentes de Python, há também um **gerenciador de contexto assíncrono**. Você o usaria com `async with`:
|
||||
|
||||
```Python
|
||||
async with lifespan(app):
|
||||
await do_stuff()
|
||||
```
|
||||
|
||||
Quando você cria um gerenciador de contexto ou um gerenciador de contexto assíncrono como mencionado acima, o que ele faz é que, antes de entrar no bloco `with`, ele irá executar o código anterior ao `yield`, e depois de sair do bloco `with`, ele irá executar o código depois do `yield`.
|
||||
|
||||
No nosso exemplo de código acima, nós não usamos ele diretamente, mas nós passamos para o FastAPI para ele usá-lo.
|
||||
|
||||
O parâmetro `lifespan` da aplicação `FastAPI` usa um **Gerenciador de Contexto Assíncrono**, então nós podemos passar nosso novo gerenciador de contexto assíncrono do `lifespan` para ele.
|
||||
|
||||
```Python hl_lines="22"
|
||||
{!../../../docs_src/events/tutorial003.py!}
|
||||
```
|
||||
|
||||
## Eventos alternativos (deprecados)
|
||||
|
||||
!!! warning "Aviso"
|
||||
A maneira recomendada para lidar com a *inicialização* e o *encerramento* é usando o parâmetro `lifespan` da aplicação `FastAPI` como descrito acima.
|
||||
|
||||
Você provavelmente pode pular essa parte.
|
||||
|
||||
Existe uma forma alternativa para definir a execução dessa lógica durante *inicialização* e durante *encerramento*.
|
||||
|
||||
Você pode definir manipuladores de eventos (funções) que precisam ser executadas antes da aplicação inicializar, ou quando a aplicação estiver encerrando.
|
||||
|
||||
Essas funções podem ser declaradas com `async def` ou `def` normal.
|
||||
|
||||
### Evento `startup`
|
||||
|
||||
Para adicionar uma função que deve rodar antes da aplicação iniciar, declare-a com o evento `"startup"`:
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!../../../docs_src/events/tutorial001.py!}
|
||||
```
|
||||
|
||||
Nesse caso, a função de manipulação de evento `startup` irá inicializar os itens do "banco de dados" (só um `dict`) com alguns valores.
|
||||
|
||||
Você pode adicionar mais que uma função de manipulação de evento.
|
||||
|
||||
E sua aplicação não irá começar a receber requisições até que todos os manipuladores de eventos de `startup` sejam concluídos.
|
||||
|
||||
### Evento `shutdown`
|
||||
|
||||
Para adicionar uma função que deve ser executada quando a aplicação estiver encerrando, declare ela com o evento `"shutdown"`:
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!../../../docs_src/events/tutorial002.py!}
|
||||
```
|
||||
|
||||
Aqui, a função de manipulação de evento `shutdown` irá escrever uma linha de texto `"Application shutdown"` no arquivo `log.txt`.
|
||||
|
||||
!!! info "Informação"
|
||||
Na função `open()`, o `mode="a"` significa "acrescentar", então, a linha irá ser adicionada depois de qualquer coisa que esteja naquele arquivo, sem sobrescrever o conteúdo anterior.
|
||||
|
||||
!!! tip "Dica"
|
||||
Perceba que nesse caso nós estamos usando a função padrão do Python `open()` que interage com um arquivo.
|
||||
|
||||
Então, isso envolve I/O (input/output), que exige "esperar" que coisas sejam escritas em disco.
|
||||
|
||||
Mas `open()` não usa `async` e `await`.
|
||||
|
||||
Então, nós declaramos uma função de manipulação de evento com o padrão `def` ao invés de `async def`.
|
||||
|
||||
### `startup` e `shutdown` juntos
|
||||
|
||||
Há uma grande chance que a lógica para sua *inicialização* e *encerramento* esteja conectada, você pode querer iniciar alguma coisa e então finalizá-la, adquirir um recurso e então liberá-lo, etc.
|
||||
|
||||
Fazendo isso em funções separadas que não compartilham lógica ou variáveis entre elas é mais difícil já que você precisa armazenar os valores em variáveis globais ou truques parecidos.
|
||||
|
||||
Por causa disso, agora é recomendado em vez disso usar o `lifespan` como explicado acima.
|
||||
|
||||
## Detalhes técnicos
|
||||
|
||||
Só um detalhe técnico para nerds curiosos. 🤓
|
||||
|
||||
Por baixo, na especificação técnica ASGI, essa é a parte do <a href="https://asgi.readthedocs.io/en/latest/specs/lifespan.html" class="external-link" target="_blank">Protocolo Lifespan</a>, e define eventos chamados `startup` e `shutdown`.
|
||||
|
||||
!!! info "Informação"
|
||||
Você pode ler mais sobre o manipulador `lifespan` do Starlette na <a href="https://www.starlette.io/lifespan/" class="external-link" target="_blank">Documentação do Lifespan Starlette</a>.
|
||||
|
||||
Incluindo como manipular estado do lifespan que pode ser usado em outras áreas do seu código.
|
||||
|
||||
## Sub Aplicações
|
||||
|
||||
🚨 Tenha em mente que esses eventos de lifespan (de inicialização e desligamento) irão somente ser executados para a aplicação principal, não para [Sub Aplicações - Montagem](./sub-applications.md){.internal-link target=_blank}.
|
||||
@@ -98,7 +98,7 @@ Após ativar o ambiente como descrito acima:
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install -e ."[dev,doc,test]"
|
||||
$ pip install -r requirements.txt
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
@@ -292,7 +292,7 @@ Agora vá para <a href="http://127.0.0.1:8000/docs" class="external-link" target
|
||||
|
||||

|
||||
|
||||
* Clique no botão "Try it out", ele permiirá que você preencha os parâmetros e interaja diretamente com a API:
|
||||
* Clique no botão "Try it out", ele permitirá que você preencha os parâmetros e interaja diretamente com a API:
|
||||
|
||||

|
||||
|
||||
@@ -430,7 +430,6 @@ Para entender mais sobre performance, veja a seção <a href="https://fastapi.ti
|
||||
|
||||
Usados por Pydantic:
|
||||
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - para JSON mais rápido <abbr title="converte uma string que chega de uma requisição HTTP para dados Python">"parsing"</abbr>.
|
||||
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - para validação de email.
|
||||
|
||||
Usados por Starlette:
|
||||
|
||||
@@ -40,6 +40,7 @@ nav:
|
||||
- Languages:
|
||||
- en: /
|
||||
- az: /az/
|
||||
- cs: /cs/
|
||||
- de: /de/
|
||||
- em: /em/
|
||||
- es: /es/
|
||||
@@ -51,6 +52,7 @@ nav:
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- lo: /lo/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
@@ -90,6 +92,7 @@ nav:
|
||||
- tutorial/static-files.md
|
||||
- Guia de Usuário Avançado:
|
||||
- advanced/index.md
|
||||
- advanced/events.md
|
||||
- Implantação:
|
||||
- deployment/index.md
|
||||
- deployment/versions.md
|
||||
@@ -144,6 +147,8 @@ extra:
|
||||
name: en - English
|
||||
- link: /az/
|
||||
name: az
|
||||
- link: /cs/
|
||||
name: cs
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /em/
|
||||
@@ -166,6 +171,8 @@ extra:
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /lo/
|
||||
name: lo - ພາສາລາວ
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
|
||||
@@ -108,7 +108,7 @@ $ python -m pip install --upgrade pip
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install -e ."[dev,doc,test]"
|
||||
$ pip install -r requirements.txt
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
311
docs/ru/docs/deployment/concepts.md
Normal file
@@ -0,0 +1,311 @@
|
||||
# Концепции развёртывания
|
||||
|
||||
Существует несколько концепций, применяемых для развёртывания приложений **FastAPI**, равно как и для любых других типов веб-приложений, среди которых Вы можете выбрать **наиболее подходящий** способ.
|
||||
|
||||
Самые важные из них:
|
||||
|
||||
* Использование более безопасного протокола HTTPS
|
||||
* Настройки запуска приложения
|
||||
* Перезагрузка приложения
|
||||
* Запуск нескольких экземпляров приложения
|
||||
* Управление памятью
|
||||
* Использование перечисленных функций перед запуском приложения.
|
||||
|
||||
Рассмотрим ниже влияние каждого из них на процесс **развёртывания**.
|
||||
|
||||
Наша конечная цель - **обслуживать клиентов Вашего API безопасно** и **бесперебойно**, с максимально эффективным использованием **вычислительных ресурсов** (например, удалённых серверов/виртуальных машин). 🚀
|
||||
|
||||
Здесь я немного расскажу Вам об этих **концепциях** и надеюсь, что у Вас сложится **интуитивное понимание**, какой способ выбрать при развертывании Вашего API в различных окружениях, возможно, даже **ещё не существующих**.
|
||||
|
||||
Ознакомившись с этими концепциями, Вы сможете **оценить и выбрать** лучший способ развёртывании **Вашего API**.
|
||||
|
||||
В последующих главах я предоставлю Вам **конкретные рецепты** развёртывания приложения FastAPI.
|
||||
|
||||
А сейчас давайте остановимся на важных **идеях этих концепций**. Эти идеи можно также применить и к другим типам веб-приложений. 💡
|
||||
|
||||
## Использование более безопасного протокола HTTPS
|
||||
|
||||
В [предыдущей главе об HTTPS](./https.md){.internal-link target=_blank} мы рассмотрели, как HTTPS обеспечивает шифрование для Вашего API.
|
||||
|
||||
Также мы заметили, что обычно для работы с HTTPS Вашему приложению нужен **дополнительный** компонент - **прокси-сервер завершения работы TLS**.
|
||||
|
||||
И если прокси-сервер не умеет сам **обновлять сертификаты HTTPS**, то нужен ещё один компонент для этого действия.
|
||||
|
||||
### Примеры инструментов для работы с HTTPS
|
||||
|
||||
Вот некоторые инструменты, которые Вы можете применять как прокси-серверы:
|
||||
|
||||
* Traefik
|
||||
* С автоматическим обновлением сертификатов ✨
|
||||
* Caddy
|
||||
* С автоматическим обновлением сертификатов ✨
|
||||
* Nginx
|
||||
* С дополнительным компонентом типа Certbot для обновления сертификатов
|
||||
* HAProxy
|
||||
* С дополнительным компонентом типа Certbot для обновления сертификатов
|
||||
* Kubernetes с Ingress Controller похожим на Nginx
|
||||
* С дополнительным компонентом типа cert-manager для обновления сертификатов
|
||||
* Использование услуг облачного провайдера (читайте ниже 👇)
|
||||
|
||||
В последнем варианте Вы можете воспользоваться услугами **облачного сервиса**, который сделает большую часть работы, включая настройку HTTPS. Это может наложить дополнительные ограничения или потребовать дополнительную плату и т.п. Зато Вам не понадобится самостоятельно заниматься настройками прокси-сервера.
|
||||
|
||||
В дальнейшем я покажу Вам некоторые конкретные примеры их применения.
|
||||
|
||||
---
|
||||
|
||||
Следующие концепции рассматривают применение программы, запускающей Ваш API (такой как Uvicorn).
|
||||
|
||||
## Программа и процесс
|
||||
|
||||
Мы часто будем встречать слова **процесс** и **программа**, потому следует уяснить отличия между ними.
|
||||
|
||||
### Что такое программа
|
||||
|
||||
Термином **программа** обычно описывают множество вещей:
|
||||
|
||||
* **Код**, который Вы написали, в нашем случае **Python-файлы**.
|
||||
* **Файл**, который может быть **исполнен** операционной системой, например `python`, `python.exe` или `uvicorn`.
|
||||
* Конкретная программа, **запущенная** операционной системой и использующая центральный процессор и память. В таком случае это также называется **процесс**.
|
||||
|
||||
### Что такое процесс
|
||||
|
||||
Термин **процесс** имеет более узкое толкование, подразумевая что-то, запущенное операционной системой (как в последнем пункте из вышестоящего абзаца):
|
||||
|
||||
* Конкретная программа, **запущенная** операционной системой.
|
||||
* Это не имеет отношения к какому-либо файлу или коду, но нечто **определённое**, управляемое и **выполняемое** операционной системой.
|
||||
* Любая программа, любой код, **могут делать что-то** только когда они **выполняются**. То есть, когда являются **работающим процессом**.
|
||||
* Процесс может быть **прерван** (или "убит") Вами или Вашей операционной системой. В результате чего он перестанет исполняться и **не будет продолжать делать что-либо**.
|
||||
* Каждое приложение, которое Вы запустили на своём компьютере, каждая программа, каждое "окно" запускает какой-то процесс. И обычно на включенном компьютере **одновременно** запущено множество процессов.
|
||||
* И **одна программа** может запустить **несколько параллельных процессов**.
|
||||
|
||||
Если Вы заглянете в "диспетчер задач" или "системный монитор" (или аналогичные инструменты) Вашей операционной системы, то увидите множество работающих процессов.
|
||||
|
||||
Вполне вероятно, что Вы увидите несколько процессов с одним и тем же названием браузерной программы (Firefox, Chrome, Edge и т. Д.). Обычно браузеры запускают один процесс на вкладку и вдобавок некоторые дополнительные процессы.
|
||||
|
||||
<img class="shadow" src="/img/deployment/concepts/image01.png">
|
||||
|
||||
---
|
||||
|
||||
Теперь, когда нам известна разница между **процессом** и **программой**, давайте продолжим обсуждение развёртывания.
|
||||
|
||||
## Настройки запуска приложения
|
||||
|
||||
В большинстве случаев когда Вы создаёте веб-приложение, то желаете, чтоб оно **работало постоянно** и непрерывно, предоставляя клиентам доступ в любое время. Хотя иногда у Вас могут быть причины, чтоб оно запускалось только при определённых условиях.
|
||||
|
||||
### Удалённый сервер
|
||||
|
||||
Когда Вы настраиваете удалённый сервер (облачный сервер, виртуальную машину и т.п.), самое простое, что можно сделать, запустить Uvicorn (или его аналог) вручную, как Вы делаете при локальной разработке.
|
||||
|
||||
Это рабочий способ и он полезен **во время разработки**.
|
||||
|
||||
Но если Вы потеряете соединение с сервером, то не сможете отслеживать - работает ли всё ещё **запущенный Вами процесс**.
|
||||
|
||||
И если сервер перезагрузится (например, после обновления или каких-то действий облачного провайдера), Вы скорее всего **этого не заметите**, чтобы снова запустить процесс вручную. Вследствие этого Ваш API останется мёртвым. 😱
|
||||
|
||||
### Автоматический запуск программ
|
||||
|
||||
Вероятно Вы пожелаете, чтоб Ваша серверная программа (такая как Uvicorn) стартовала автоматически при включении сервера, без **человеческого вмешательства** и всегда могла управлять Вашим API (так как Uvicorn запускает приложение FastAPI).
|
||||
|
||||
### Отдельная программа
|
||||
|
||||
Для этого у обычно используют отдельную программу, которая следит за тем, чтобы Ваши приложения запускались при включении сервера. Такой подход гарантирует, что другие компоненты или приложения также будут запущены, например, база данных
|
||||
|
||||
### Примеры инструментов, управляющих запуском программ
|
||||
|
||||
Вот несколько примеров, которые могут справиться с такой задачей:
|
||||
|
||||
* Docker
|
||||
* Kubernetes
|
||||
* Docker Compose
|
||||
* Docker в режиме Swarm
|
||||
* Systemd
|
||||
* Supervisor
|
||||
* Использование услуг облачного провайдера
|
||||
* Прочие...
|
||||
|
||||
Я покажу Вам некоторые примеры их использования в следующих главах.
|
||||
|
||||
## Перезапуск
|
||||
|
||||
Вы, вероятно, также пожелаете, чтоб Ваше приложение **перезапускалось**, если в нём произошёл сбой.
|
||||
|
||||
### Мы ошибаемся
|
||||
|
||||
Все люди совершают **ошибки**. Программное обеспечение почти *всегда* содержит **баги** спрятавшиеся в разных местах. 🐛
|
||||
|
||||
И мы, будучи разработчиками, продолжаем улучшать код, когда обнаруживаем в нём баги или добавляем новый функционал (возможно, добавляя при этом баги 😅).
|
||||
|
||||
### Небольшие ошибки обрабатываются автоматически
|
||||
|
||||
Когда Вы создаёте свои API на основе FastAPI и допускаете в коде ошибку, то FastAPI обычно остановит её распространение внутри одного запроса, при обработке которого она возникла. 🛡
|
||||
|
||||
Клиент получит ошибку **500 Internal Server Error** в ответ на свой запрос, но приложение не сломается и будет продолжать работать с последующими запросами.
|
||||
|
||||
### Большие ошибки - Падение приложений
|
||||
|
||||
Тем не менее, может случиться так, что ошибка вызовет **сбой всего приложения** или даже сбой в Uvicorn, а то и в самом Python. 💥
|
||||
|
||||
Но мы всё ещё хотим, чтобы приложение **продолжало работать** несмотря на эту единственную ошибку, обрабатывая, как минимум, запросы к *операциям пути* не имеющим ошибок.
|
||||
|
||||
### Перезапуск после падения
|
||||
|
||||
Для случаев, когда ошибки приводят к сбою в запущенном **процессе**, Вам понадобится добавить компонент, который **перезапустит** процесс хотя бы пару раз...
|
||||
|
||||
!!! tip "Заметка"
|
||||
... Если приложение падает сразу же после запуска, вероятно бесполезно его бесконечно перезапускать. Но полагаю, Вы заметите такое поведение во время разработки или, по крайней мере, сразу после развёртывания.
|
||||
|
||||
Так что давайте сосредоточимся на конкретных случаях, когда приложение может полностью выйти из строя, но всё ещё есть смысл его запустить заново.
|
||||
|
||||
Возможно Вы захотите, чтоб был некий **внешний компонент**, ответственный за перезапуск Вашего приложения даже если уже не работает Uvicorn или Python. То есть ничего из того, что написано в Вашем коде внутри приложения, не может быть выполнено в принципе.
|
||||
|
||||
### Примеры инструментов для автоматического перезапуска
|
||||
|
||||
В большинстве случаев инструменты **запускающие программы при старте сервера** умеют **перезапускать** эти программы.
|
||||
|
||||
В качестве примера можно взять те же:
|
||||
|
||||
* Docker
|
||||
* Kubernetes
|
||||
* Docker Compose
|
||||
* Docker в режиме Swarm
|
||||
* Systemd
|
||||
* Supervisor
|
||||
* Использование услуг облачного провайдера
|
||||
* Прочие...
|
||||
|
||||
## Запуск нескольких экземпляров приложения (Репликация) - Процессы и память
|
||||
|
||||
Приложение FastAPI, управляемое серверной программой (такой как Uvicorn), запускается как **один процесс** и может обслуживать множество клиентов одновременно.
|
||||
|
||||
Но часто Вам может понадобиться несколько одновременно работающих одинаковых процессов.
|
||||
|
||||
### Множество процессов - Воркеры (Workers)
|
||||
|
||||
Если количество Ваших клиентов больше, чем может обслужить один процесс (допустим, что виртуальная машина не слишком мощная), но при этом Вам доступно **несколько ядер процессора**, то Вы можете запустить **несколько процессов** одного и того же приложения параллельно и распределить запросы между этими процессами.
|
||||
|
||||
**Несколько запущенных процессов** одной и той же API-программы часто называют **воркерами**.
|
||||
|
||||
### Процессы и порты́
|
||||
|
||||
Помните ли Вы, как на странице [Об HTTPS](./https.md){.internal-link target=_blank} мы обсуждали, что на сервере только один процесс может слушать одну комбинацию IP-адреса и порта?
|
||||
|
||||
С тех пор ничего не изменилось.
|
||||
|
||||
Соответственно, чтобы иметь возможность работать с **несколькими процессами** одновременно, должен быть **один процесс, прослушивающий порт** и затем каким-либо образом передающий данные каждому рабочему процессу.
|
||||
|
||||
### У каждого процесса своя память
|
||||
|
||||
Работающая программа загружает в память данные, необходимые для её работы, например, переменные содержащие модели машинного обучения или большие файлы. Каждая переменная **потребляет некоторое количество оперативной памяти (RAM)** сервера.
|
||||
|
||||
Обычно процессы **не делятся памятью друг с другом**. Сие означает, что каждый работающий процесс имеет свои данные, переменные и свой кусок памяти. И если для выполнения Вашего кода процессу нужно много памяти, то **каждый такой же процесс** запущенный дополнительно, потребует такого же количества памяти.
|
||||
|
||||
### Память сервера
|
||||
|
||||
Допустим, что Ваш код загружает модель машинного обучения **размером 1 ГБ**. Когда Вы запустите своё API как один процесс, он займёт в оперативной памяти не менее 1 ГБ. А если Вы запустите **4 таких же процесса** (4 воркера), то каждый из них займёт 1 ГБ оперативной памяти. В результате Вашему API потребуется **4 ГБ оперативной памяти (RAM)**.
|
||||
|
||||
И если Ваш удалённый сервер или виртуальная машина располагает только 3 ГБ памяти, то попытка загрузить в неё 4 ГБ данных вызовет проблемы. 🚨
|
||||
|
||||
### Множество процессов - Пример
|
||||
|
||||
В этом примере **менеджер процессов** запустит и будет управлять двумя **воркерами**.
|
||||
|
||||
Менеджер процессов будет слушать определённый **сокет** (IP:порт) и передавать данные работающим процессам.
|
||||
|
||||
Каждый из этих процессов будет запускать Ваше приложение для обработки полученного **запроса** и возвращения вычисленного **ответа** и они будут использовать оперативную память.
|
||||
|
||||
<img src="/img/deployment/concepts/process-ram.svg">
|
||||
|
||||
Безусловно, на этом же сервере будут работать и **другие процессы**, которые не относятся к Вашему приложению.
|
||||
|
||||
Интересная деталь - обычно в течение времени процент **использования центрального процессора (CPU)** каждым процессом может очень сильно **изменяться**, но объём занимаемой **оперативной памяти (RAM)** остаётся относительно **стабильным**.
|
||||
|
||||
Если у Вас есть API, который каждый раз выполняет сопоставимый объем вычислений, и у Вас много клиентов, то **загрузка процессора**, вероятно, *также будет стабильной* (вместо того, чтобы постоянно быстро увеличиваться и уменьшаться).
|
||||
|
||||
### Примеры стратегий и инструментов для запуска нескольких экземпляров приложения
|
||||
|
||||
Существует несколько подходов для достижения целей репликации и я расскажу Вам больше о конкретных стратегиях в следующих главах, например, когда речь пойдет о Docker и контейнерах.
|
||||
|
||||
Основное ограничение при этом - только **один** компонент может работать с определённым **портом публичного IP**. И должен быть способ **передачи** данных между этим компонентом и копиями **процессов/воркеров**.
|
||||
|
||||
Вот некоторые возможные комбинации и стратегии:
|
||||
|
||||
* **Gunicorn** управляющий **воркерами Uvicorn**
|
||||
* Gunicorn будет выступать как **менеджер процессов**, прослушивая **IP:port**. Необходимое количество запущенных экземпляров приложения будет осуществляться посредством запуска **множества работающих процессов Uvicorn**.
|
||||
* **Uvicorn** управляющий **воркерами Uvicorn**
|
||||
* Один процесс Uvicorn будет выступать как **менеджер процессов**, прослушивая **IP:port**. Он будет запускать **множество работающих процессов Uvicorn**.
|
||||
* **Kubernetes** и аналогичные **контейнерные системы**
|
||||
* Какой-то компонент в **Kubernetes** будет слушать **IP:port**. Необходимое количество запущенных экземпляров приложения будет осуществляться посредством запуска **нескольких контейнеров**, в каждом из которых работает **один процесс Uvicorn**.
|
||||
* **Облачные сервисы**, которые позаботятся обо всём за Вас
|
||||
* Возможно, что облачный сервис умеет **управлять запуском дополнительных экземпляров приложения**. Вероятно, он потребует, чтоб Вы указали - какой **процесс** или **образ** следует клонировать. Скорее всего, Вы укажете **один процесс Uvicorn** и облачный сервис будет запускать его копии при необходимости.
|
||||
|
||||
!!! tip "Заметка"
|
||||
Если Вы не знаете, что такое **контейнеры**, Docker или Kubernetes, не переживайте.
|
||||
|
||||
Я поведаю Вам о контейнерах, образах, Docker, Kubernetes и т.п. в главе: [FastAPI внутри контейнеров - Docker](./docker.md){.internal-link target=_blank}.
|
||||
|
||||
## Шаги, предшествующие запуску
|
||||
|
||||
Часто бывает, что Вам необходимо произвести какие-то подготовительные шаги **перед запуском** своего приложения.
|
||||
|
||||
Например, запустить **миграции базы данных**.
|
||||
|
||||
Но в большинстве случаев такие действия достаточно произвести **однократно**.
|
||||
|
||||
Поэтому Вам нужен будет **один процесс**, выполняющий эти **подготовительные шаги** до запуска приложения.
|
||||
|
||||
Также Вам нужно будет убедиться, что этот процесс выполнил подготовительные шаги *даже* если впоследствии Вы запустите **несколько процессов** (несколько воркеров) самого приложения. Если бы эти шаги выполнялись в каждом **клонированном процессе**, они бы **дублировали** работу, пытаясь выполнить её **параллельно**. И если бы эта работа была бы чем-то деликатным, вроде миграции базы данных, то это может вызвать конфликты между ними.
|
||||
|
||||
Безусловно, возможны случаи, когда нет проблем при выполнении предварительной подготовки параллельно или несколько раз. Тогда Вам повезло, работать с ними намного проще.
|
||||
|
||||
!!! tip "Заметка"
|
||||
Имейте в виду, что в некоторых случаях запуск Вашего приложения **может не требовать каких-либо предварительных шагов вовсе**.
|
||||
|
||||
Что ж, тогда Вам не нужно беспокоиться об этом. 🤷
|
||||
|
||||
### Примеры стратегий запуска предварительных шагов
|
||||
|
||||
Существует **сильная зависимость** от того, как Вы **развёртываете свою систему**, запускаете программы, обрабатываете перезапуски и т.д.
|
||||
|
||||
Вот некоторые возможные идеи:
|
||||
|
||||
* При использовании Kubernetes нужно предусмотреть "инициализирующий контейнер", запускаемый до контейнера с приложением.
|
||||
* Bash-скрипт, выполняющий предварительные шаги, а затем запускающий приложение.
|
||||
* При этом Вам всё ещё нужно найти способ - как запускать/перезапускать *такой* bash-скрипт, обнаруживать ошибки и т.п.
|
||||
|
||||
!!! tip "Заметка"
|
||||
Я приведу Вам больше конкретных примеров работы с контейнерами в главе: [FastAPI внутри контейнеров - Docker](./docker.md){.internal-link target=_blank}.
|
||||
|
||||
## Утилизация ресурсов
|
||||
|
||||
Ваш сервер располагает ресурсами, которые Ваши программы могут потреблять или **утилизировать**, а именно - время работы центрального процессора и объём оперативной памяти.
|
||||
|
||||
Как много системных ресурсов Вы предполагаете потребить/утилизировать? Если не задумываться, то можно ответить - "немного", но на самом деле Вы, вероятно, пожелаете использовать **максимально возможное количество**.
|
||||
|
||||
Если Вы платите за содержание трёх серверов, но используете лишь малую часть системных ресурсов каждого из них, то Вы **выбрасываете деньги на ветер**, а также **впустую тратите электроэнергию** и т.п.
|
||||
|
||||
В таком случае было бы лучше обойтись двумя серверами, но более полно утилизировать их ресурсы (центральный процессор, оперативную память, жёсткий диск, сети передачи данных и т.д).
|
||||
|
||||
С другой стороны, если Вы располагаете только двумя серверами и используете **на 100% их процессоры и память**, но какой-либо процесс запросит дополнительную память, то операционная система сервера будет использовать жёсткий диск для расширения оперативной памяти (а диск работает в тысячи раз медленнее), а то вовсе **упадёт**. Или если какому-то процессу понадобится произвести вычисления, то ему придётся подождать, пока процессор освободится.
|
||||
|
||||
В такой ситуации лучше подключить **ещё один сервер** и перераспределить процессы между серверами, чтоб всем **хватало памяти и процессорного времени**.
|
||||
|
||||
Также есть вероятность, что по какой-то причине возник **всплеск** запросов к Вашему API. Возможно, это был вирус, боты или другие сервисы начали пользоваться им. И для таких происшествий Вы можете захотеть иметь дополнительные ресурсы.
|
||||
|
||||
При настройке логики развёртываний, Вы можете указать **целевое значение** утилизации ресурсов, допустим, **от 50% до 90%**. Обычно эти метрики и используют.
|
||||
|
||||
Вы можете использовать простые инструменты, такие как `htop`, для отслеживания загрузки центрального процессора и оперативной памяти сервера, в том числе каждым процессом. Или более сложные системы мониторинга нескольких серверов.
|
||||
|
||||
## Резюме
|
||||
|
||||
Вы прочитали некоторые из основных концепций, которые необходимо иметь в виду при принятии решения о развертывании приложений:
|
||||
|
||||
* Использование более безопасного протокола HTTPS
|
||||
* Настройки запуска приложения
|
||||
* Перезагрузка приложения
|
||||
* Запуск нескольких экземпляров приложения
|
||||
* Управление памятью
|
||||
* Использование перечисленных функций перед запуском приложения.
|
||||
|
||||
Осознание этих идей и того, как их применять, должно дать Вам интуитивное понимание, необходимое для принятия решений при настройке развертываний. 🤓
|
||||
|
||||
В следующих разделах я приведу более конкретные примеры возможных стратегий, которым Вы можете следовать. 🚀
|
||||
198
docs/ru/docs/deployment/https.md
Normal file
@@ -0,0 +1,198 @@
|
||||
# Об HTTPS
|
||||
|
||||
Обычно представляется, что HTTPS это некая опция, которая либо "включена", либо нет.
|
||||
|
||||
Но всё несколько сложнее.
|
||||
|
||||
!!! tip "Заметка"
|
||||
Если Вы торопитесь или Вам не интересно, можете перейти на следующую страницу этого пошагового руководства по размещению приложений на серверах с использованием различных технологий.
|
||||
|
||||
Чтобы **изучить основы HTTPS** для клиента, перейдите по ссылке <a href="https://howhttps.works/" class="external-link" target="_blank">https://howhttps.works/</a>.
|
||||
|
||||
Здесь же представлены некоторые концепции, которые **разработчик** должен иметь в виду при размышлениях об HTTPS:
|
||||
|
||||
* Протокол HTTPS предполагает, что **серверу** нужно **располагать "сертификатами"** сгенерированными **третьей стороной**.
|
||||
* На самом деле эти сертификаты **приобретены** у третьей стороны, а не "сгенерированы".
|
||||
* У сертификатов есть **срок годности**.
|
||||
* Срок годности **истекает**.
|
||||
* По истечении срока годности их нужно **обновить**, то есть **снова получить** у третьей стороны.
|
||||
* Шифрование соединения происходит **на уровне протокола TCP**.
|
||||
* Протокол TCP находится на один уровень **ниже протокола HTTP**.
|
||||
* Поэтому **проверка сертификатов и шифрование** происходит **до HTTP**.
|
||||
* **TCP не знает о "доменах"**, но знает об IP-адресах.
|
||||
* Информация о **запрашиваемом домене** извлекается из запроса **на уровне HTTP**.
|
||||
* **Сертификаты HTTPS** "сертифицируют" **конкретный домен**, но проверка сертификатов и шифрование данных происходит на уровне протокола TCP, то есть **до того**, как станет известен домен-получатель данных.
|
||||
* **По умолчанию** это означает, что у Вас может быть **только один сертификат HTTPS на один IP-адрес**.
|
||||
* Не важно, насколько большой у Вас сервер и насколько маленькие приложения на нём могут быть.
|
||||
* Однако, у этой проблемы есть **решение**.
|
||||
* Существует **расширение** протокола **TLS** (который работает на уровне TCP, то есть до HTTP) называемое **<a href="https://en.wikipedia.org/wiki/Server_Name_Indication" class="external-link" target="_blank"><abbr title="Указание имени сервера">SNI</abbr></a>**.
|
||||
* Расширение SNI позволяет одному серверу (с **одним IP-адресом**) иметь **несколько сертификатов HTTPS** и обслуживать **множество HTTPS-доменов/приложений**.
|
||||
* Чтобы эта конструкция работала, **один** её компонент (программа) запущенный на сервере и слушающий **публичный IP-адрес**, должен иметь **все сертификаты HTTPS** для этого сервера.
|
||||
* **После** установления защищённого соединения, протоколом передачи данных **остаётся HTTP**.
|
||||
* Но данные теперь **зашифрованы**, несмотря на то, что они передаются по **протоколу HTTP**.
|
||||
|
||||
Обычной практикой является иметь **одну программу/HTTP-сервер** запущенную на сервере (машине, хосте и т.д.) и **ответственную за всю работу с HTTPS**:
|
||||
|
||||
* получение **зашифрованных HTTPS-запросов**
|
||||
* отправка **расшифрованных HTTP запросов** в соответствующее HTTP-приложение, работающее на том же сервере (в нашем случае, это приложение **FastAPI**)
|
||||
* получние **HTTP-ответа** от приложения
|
||||
* **шифрование ответа** используя подходящий **сертификат HTTPS**
|
||||
* отправка зашифрованного **HTTPS-ответа клиенту**.
|
||||
Такой сервер часто называют **<a href="https://en.wikipedia.org/wiki/TLS_termination_proxy" class="external-link" target="_blank">Прокси-сервер завершения работы TLS</a>** или просто "прокси-сервер".
|
||||
|
||||
Вот некоторые варианты, которые Вы можете использовать в качестве такого прокси-сервера:
|
||||
|
||||
* Traefik (может обновлять сертификаты)
|
||||
* Caddy (может обновлять сертификаты)
|
||||
* Nginx
|
||||
* HAProxy
|
||||
|
||||
## Let's Encrypt (центр сертификации)
|
||||
|
||||
До появления Let's Encrypt **сертификаты HTTPS** приходилось покупать у третьих сторон.
|
||||
|
||||
Процесс получения такого сертификата был трудоёмким, требовал предоставления подтверждающих документов и сертификаты стоили дорого.
|
||||
|
||||
Но затем консорциумом Linux Foundation был создан проект **<a href="https://letsencrypt.org/" class="external-link" target="_blank">Let's Encrypt</a>**.
|
||||
|
||||
Он автоматически предоставляет **бесплатные сертификаты HTTPS**. Эти сертификаты используют все стандартные криптографические способы шифрования. Они имеют небольшой срок годности (около 3 месяцев), благодаря чему они даже **более безопасны**.
|
||||
|
||||
При запросе на получение сертификата, он автоматически генерируется и домен проверяется на безопасность. Это позволяет обновлять сертификаты автоматически.
|
||||
|
||||
Суть идеи в автоматическом получении и обновлении этих сертификатов, чтобы все могли пользоваться **безопасным HTTPS. Бесплатно. В любое время.**
|
||||
|
||||
## HTTPS для разработчиков
|
||||
|
||||
Ниже, шаг за шагом, с заострением внимания на идеях, важных для разработчика, описано, как может выглядеть HTTPS API.
|
||||
|
||||
### Имя домена
|
||||
|
||||
Чаще всего, всё начинается с **приобретения имени домена**. Затем нужно настроить DNS-сервер (вероятно у того же провайдера, который выдал Вам домен).
|
||||
|
||||
Далее, возможно, Вы получаете "облачный" сервер (виртуальную машину) или что-то типа этого, у которого есть <abbr title="Не изменяемый">постоянный</abbr> **публичный IP-адрес**.
|
||||
|
||||
На DNS-сервере (серверах) Вам следует настроить соответствующую ресурсную запись ("`запись A`"), указав, что **Ваш домен** связан с публичным **IP-адресом Вашего сервера**.
|
||||
|
||||
Обычно эту запись достаточно указать один раз, при первоначальной настройке всего сервера.
|
||||
|
||||
!!! tip "Заметка"
|
||||
Уровни протоколов, работающих с именами доменов, намного ниже HTTPS, но об этом следует упомянуть здесь, так как всё зависит от доменов и IP-адресов.
|
||||
|
||||
### DNS
|
||||
|
||||
Теперь давайте сфокусируемся на работе с HTTPS.
|
||||
|
||||
Всё начинается с того, что браузер спрашивает у **DNS-серверов**, какой **IP-адрес связан с доменом**, для примера возьмём домен `someapp.example.com`.
|
||||
|
||||
DNS-сервера присылают браузеру определённый **IP-адрес**, тот самый публичный IP-адрес Вашего сервера, который Вы указали в ресурсной "записи А" при настройке.
|
||||
|
||||
<img src="/img/deployment/https/https01.svg">
|
||||
|
||||
### Рукопожатие TLS
|
||||
|
||||
В дальнейшем браузер будет взаимодействовать с этим IP-адресом через **port 443** (общепринятый номер порта для HTTPS).
|
||||
|
||||
Первым шагом будет установление соединения между клиентом (браузером) и сервером и выбор криптографического ключа (для шифрования).
|
||||
|
||||
<img src="/img/deployment/https/https02.svg">
|
||||
|
||||
Эта часть клиент-серверного взаимодействия устанавливает TLS-соединение и называется **TLS-рукопожатием**.
|
||||
|
||||
### TLS с расширением SNI
|
||||
|
||||
На сервере **только один процесс** может прослушивать определённый **порт** определённого **IP-адреса**. На сервере могут быть и другие процессы, слушающие другие порты этого же IP-адреса, но никакой процесс не может быть привязан к уже занятой комбинации IP-адрес:порт. Эта комбинация называется "сокет".
|
||||
|
||||
По умолчанию TLS (HTTPS) использует порт `443`. Потому этот же порт будем использовать и мы.
|
||||
|
||||
И раз уж только один процесс может слушать этот порт, то это будет процесс **прокси-сервера завершения работы TLS**.
|
||||
|
||||
Прокси-сервер завершения работы TLS будет иметь доступ к одному или нескольким **TLS-сертификатам** (сертификаты HTTPS).
|
||||
|
||||
Используя **расширение SNI** упомянутое выше, прокси-сервер из имеющихся сертификатов TLS (HTTPS) выберет тот, который соответствует имени домена, указанному в запросе от клиента.
|
||||
|
||||
То есть будет выбран сертификат для домена `someapp.example.com`.
|
||||
|
||||
<img src="/img/deployment/https/https03.svg">
|
||||
|
||||
Клиент уже **доверяет** тому, кто выдал этот TLS-сертификат (в нашем случае - Let's Encrypt, но мы ещё обсудим это), потому может **проверить**, действителен ли полученный от сервера сертификат.
|
||||
|
||||
Затем, используя этот сертификат, клиент и прокси-сервер **выбирают способ шифрования** данных для устанавливаемого **TCP-соединения**. На этом операция **TLS-рукопожатия** завершена.
|
||||
|
||||
В дальнейшем клиент и сервер будут взаимодействовать по **зашифрованному TCP-соединению**, как предлагается в протоколе TLS. И на основе этого TCP-соедениния будет создано **HTTP-соединение**.
|
||||
|
||||
Таким образом, **HTTPS** это тот же **HTTP**, но внутри **безопасного TLS-соединения** вместо чистого (незашифрованного) TCP-соединения.
|
||||
|
||||
!!! tip "Заметка"
|
||||
Обратите внимание, что шифрование происходит на **уровне TCP**, а не на более высоком уровне HTTP.
|
||||
|
||||
### HTTPS-запрос
|
||||
|
||||
Теперь, когда между клиентом и сервером (в нашем случае, браузером и прокси-сервером) создано **зашифрованное TCP-соединение**, они могут начать **обмен данными по протоколу HTTP**.
|
||||
|
||||
Так клиент отправляет **HTTPS-запрос**. То есть обычный HTTP-запрос, но через зашифрованное TLS-содинение.
|
||||
|
||||
<img src="/img/deployment/https/https04.svg">
|
||||
|
||||
### Расшифровка запроса
|
||||
|
||||
Прокси-сервер, используя согласованный с клиентом ключ, расшифрует полученный **зашифрованный запрос** и передаст **обычный (незашифрованный) HTTP-запрос** процессу, запускающему приложение (например, процессу Uvicorn запускающему приложение FastAPI).
|
||||
|
||||
<img src="/img/deployment/https/https05.svg">
|
||||
|
||||
### HTTP-ответ
|
||||
|
||||
Приложение обработает запрос и вернёт **обычный (незашифрованный) HTTP-ответ** прокси-серверу.
|
||||
|
||||
<img src="/img/deployment/https/https06.svg">
|
||||
|
||||
### HTTPS-ответ
|
||||
|
||||
Пркоси-сервер **зашифрует ответ** используя ранее согласованный с клиентом способ шифрования (которые содержатся в сертификате для домена `someapp.example.com`) и отправит его браузеру.
|
||||
|
||||
Наконец, браузер проверит ответ, в том числе, что тот зашифрован с нужным ключом, **расшифрует его** и обработает.
|
||||
|
||||
<img src="/img/deployment/https/https07.svg">
|
||||
|
||||
Клиент (браузер) знает, что ответ пришёл от правильного сервера, так как использует методы шифрования, согласованные ими раннее через **HTTPS-сертификат**.
|
||||
|
||||
### Множество приложений
|
||||
|
||||
На одном и том же сервере (или серверах) можно разместить **множество приложений**, например, другие программы с API или базы данных.
|
||||
|
||||
Напомню, что только один процесс (например, прокси-сервер) может прослушивать определённый порт определённого IP-адреса.
|
||||
Но другие процессы и приложения тоже могут работать на этом же сервере (серверах), если они не пытаются использовать уже занятую **комбинацию IP-адреса и порта** (сокет).
|
||||
|
||||
<img src="/img/deployment/https/https08.svg">
|
||||
|
||||
Таким образом, сервер завершения TLS может обрабатывать HTTPS-запросы и использовать сертификаты для **множества доменов** или приложений и передавать запросы правильным адресатам (другим приложениям).
|
||||
|
||||
### Обновление сертификата
|
||||
|
||||
В недалёком будущем любой сертификат станет **просроченным** (примерно через три месяца после получения).
|
||||
|
||||
Когда это произойдёт, можно запустить другую программу, которая подключится к Let's Encrypt и обновит сертификат(ы). Существуют прокси-серверы, которые могут сделать это действие самостоятельно.
|
||||
|
||||
<img src="/img/deployment/https/https.svg">
|
||||
|
||||
**TLS-сертификаты** не привязаны к IP-адресу, но **связаны с именем домена**.
|
||||
|
||||
Так что при обновлении сертификатов программа должна **подтвердить** центру сертификации (Let's Encrypt), что обновление запросил **"владелец", который контролирует этот домен**.
|
||||
|
||||
Есть несколько путей осуществления этого. Самые популярные из них:
|
||||
|
||||
* **Изменение записей DNS**.
|
||||
* Для такого варианта Ваша программа обновления должна уметь работать с API DNS-провайдера, обслуживающего Ваши DNS-записи. Не у всех провайдеров есть такой API, так что этот способ не всегда применим.
|
||||
* **Запуск в качестве программы-сервера** (как минимум, на время обновления сертификатов) на публичном IP-адресе домена.
|
||||
* Как уже не раз упоминалось, только один процесс может прослушивать определённый порт определённого IP-адреса.
|
||||
* Это одна из причин использования прокси-сервера ещё и в качестве программы обновления сертификатов.
|
||||
* В случае, если обновлением сертификатов занимается другая программа, Вам понадобится остановить прокси-сервер, запустить программу обновления сертификатов на сокете, предназначенном для прокси-сервера, настроить прокси-сервер на работу с новыми сертификатами и перезапустить его. Эта схема далека от идеальной, так как Ваши приложения будут недоступны на время отключения прокси-сервера.
|
||||
|
||||
Весь этот процесс обновления, одновременный с обслуживанием запросов, является одной из основных причин, по которой желательно иметь **отдельную систему для работы с HTTPS** в виде прокси-сервера завершения TLS, а не просто использовать сертификаты TLS непосредственно с сервером приложений (например, Uvicorn).
|
||||
|
||||
## Резюме
|
||||
|
||||
Наличие **HTTPS** очень важно и довольно **критично** в большинстве случаев. Однако, Вам, как разработчику, не нужно тратить много сил на это, достаточно **понимать эти концепции** и принципы их работы.
|
||||
|
||||
Но узнав базовые основы **HTTPS** Вы можете легко совмещать разные инструменты, которые помогут Вам в дальнейшей разработке.
|
||||
|
||||
В следующих главах я покажу Вам несколько примеров, как настраивать **HTTPS** для приложений **FastAPI**. 🔒
|
||||
150
docs/ru/docs/deployment/manually.md
Normal file
@@ -0,0 +1,150 @@
|
||||
# Запуск сервера вручную - Uvicorn
|
||||
|
||||
Для запуска приложения **FastAPI** на удалённой серверной машине Вам необходим программный сервер, поддерживающий протокол ASGI, такой как **Uvicorn**.
|
||||
|
||||
Существует три наиболее распространённые альтернативы:
|
||||
|
||||
* <a href="https://www.uvicorn.org/" class="external-link" target="_blank">Uvicorn</a>: высокопроизводительный ASGI сервер.
|
||||
* <a href="https://pgjones.gitlab.io/hypercorn/" class="external-link" target="_blank">Hypercorn</a>: ASGI сервер, помимо прочего поддерживающий HTTP/2 и Trio.
|
||||
* <a href="https://github.com/django/daphne" class="external-link" target="_blank">Daphne</a>: ASGI сервер, созданный для Django Channels.
|
||||
|
||||
## Сервер как машина и сервер как программа
|
||||
|
||||
В этих терминах есть некоторые различия и Вам следует запомнить их. 💡
|
||||
|
||||
Слово "**сервер**" чаще всего используется в двух контекстах:
|
||||
|
||||
- удалённый или расположенный в "облаке" компьютер (физическая или виртуальная машина).
|
||||
- программа, запущенная на таком компьютере (например, Uvicorn).
|
||||
|
||||
Просто запомните, если Вам встретился термин "сервер", то обычно он подразумевает что-то из этих двух смыслов.
|
||||
|
||||
Когда имеют в виду именно удалённый компьютер, часто говорят просто **сервер**, но ещё его называют **машина**, **ВМ** (виртуальная машина), **нода**. Все эти термины обозначают одно и то же - удалённый компьютер, обычно под управлением Linux, на котором Вы запускаете программы.
|
||||
|
||||
## Установка программного сервера
|
||||
|
||||
Вы можете установить сервер, совместимый с протоколом ASGI, так:
|
||||
|
||||
=== "Uvicorn"
|
||||
|
||||
* <a href="https://www.uvicorn.org/" class="external-link" target="_blank">Uvicorn</a>, молниесный ASGI сервер, основанный на библиотеках uvloop и httptools.
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "uvicorn[standard]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
!!! tip "Подсказка"
|
||||
С опцией `standard`, Uvicorn будет установливаться и использоваться с некоторыми дополнительными рекомендованными зависимостями.
|
||||
|
||||
В них входит `uvloop`, высокопроизводительная замена `asyncio`, которая значительно ускоряет работу асинхронных программ.
|
||||
|
||||
=== "Hypercorn"
|
||||
|
||||
* <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>, ASGI сервер, поддерживающий протокол HTTP/2.
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install hypercorn
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
...или какой-либо другой ASGI сервер.
|
||||
|
||||
## Запуск серверной программы
|
||||
|
||||
Затем запустите Ваше приложение так же, как было указано в руководстве ранее, но без опции `--reload`:
|
||||
|
||||
=== "Uvicorn"
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --host 0.0.0.0 --port 80
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://0.0.0.0:80 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
=== "Hypercorn"
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ hypercorn main:app --bind 0.0.0.0:80
|
||||
|
||||
Running on 0.0.0.0:8080 over http (CTRL + C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
!!! warning "Предупреждение"
|
||||
|
||||
Не забудьте удалить опцию `--reload`, если ранее пользовались ею.
|
||||
|
||||
Включение опции `--reload` требует дополнительных ресурсов, влияет на стабильность работы приложения и может повлечь прочие неприятности.
|
||||
|
||||
Она сильно помогает во время **разработки**, но **не следует** использовать её при **реальной работе** приложения.
|
||||
|
||||
## Hypercorn с Trio
|
||||
|
||||
Starlette и **FastAPI** основаны на <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a>, которая делает их совместимыми как с <a href="https://docs.python.org/3/library/asyncio-task.html" class="external-link" target="_blank">asyncio</a> - стандартной библиотекой Python, так и с <a href="https://trio.readthedocs.io/en/stable/" class="external-link" target="_blank">Trio</a>.
|
||||
|
||||
|
||||
Тем не менее Uvicorn совместим только с asyncio и обычно используется совместно с <a href="https://github.com/MagicStack/uvloop" class="external-link" target="_blank">`uvloop`</a>, высокопроизводительной заменой `asyncio`.
|
||||
|
||||
Но если Вы хотите использовать **Trio** напрямую, то можете воспользоваться **Hypercorn**, так как они совместимы. ✨
|
||||
|
||||
### Установка Hypercorn с Trio
|
||||
|
||||
Для начала, Вам нужно установить Hypercorn с поддержкой Trio:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "hypercorn[trio]"
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### Запуск с Trio
|
||||
|
||||
Далее запустите Hypercorn с опцией `--worker-class` и аргументом `trio`:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ hypercorn main:app --worker-class trio
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Hypercorn, в свою очередь, запустит Ваше приложение использующее Trio.
|
||||
|
||||
Таким образом, Вы сможете использовать Trio в своём приложении. Но лучше использовать AnyIO, для сохранения совместимости и с Trio, и с asyncio. 🎉
|
||||
|
||||
## Концепции развёртывания
|
||||
|
||||
В вышеприведённых примерах серверные программы (например Uvicorn) запускали только **один процесс**, принимающий входящие запросы с любого IP (на это указывал аргумент `0.0.0.0`) на определённый порт (в примерах мы указывали порт `80`).
|
||||
|
||||
Это основная идея. Но возможно, Вы озаботитесь добавлением дополнительных возможностей, таких как:
|
||||
|
||||
* Использование более безопасного протокола HTTPS
|
||||
* Настройки запуска приложения
|
||||
* Перезагрузка приложения
|
||||
* Запуск нескольких экземпляров приложения
|
||||
* Управление памятью
|
||||
* Использование перечисленных функций перед запуском приложения.
|
||||
|
||||
Я поведаю Вам больше о каждой из этих концепций в следующих главах, с конкретными примерами стратегий работы с ними. 🚀
|
||||
@@ -439,7 +439,6 @@ item: Item
|
||||
|
||||
Используется Pydantic:
|
||||
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - для более быстрого JSON <abbr title="преобразования строки, полученной из HTTP-запроса, в данные Python">"парсинга"</abbr>.
|
||||
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - для проверки электронной почты.
|
||||
|
||||
Используется Starlette:
|
||||
|
||||
309
docs/ru/docs/tutorial/body-multiple-params.md
Normal file
@@ -0,0 +1,309 @@
|
||||
# Body - Множество параметров
|
||||
|
||||
Теперь, когда мы увидели, как использовать `Path` и `Query` параметры, давайте рассмотрим более продвинутые примеры обьявления тела запроса.
|
||||
|
||||
## Обьединение `Path`, `Query` и параметров тела запроса
|
||||
|
||||
Во-первых, конечно, вы можете объединять параметры `Path`, `Query` и объявления тела запроса в своих функциях обработки, **FastAPI** автоматически определит, что с ними нужно делать.
|
||||
|
||||
Вы также можете объявить параметры тела запроса как необязательные, установив значение по умолчанию, равное `None`:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="18-20"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="18-20"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="19-21"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10+ non-Annotated"
|
||||
|
||||
!!! Заметка
|
||||
Рекомендуется использовать `Annotated` версию, если это возможно.
|
||||
|
||||
```Python hl_lines="17-19"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+ non-Annotated"
|
||||
|
||||
!!! Заметка
|
||||
Рекомендуется использовать версию с `Annotated`, если это возможно.
|
||||
|
||||
```Python hl_lines="19-21"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! Заметка
|
||||
Заметьте, что в данном случае параметр `item`, который будет взят из тела запроса, необязателен. Так как было установлено значение `None` по умолчанию.
|
||||
|
||||
## Несколько параметров тела запроса
|
||||
|
||||
В предыдущем примере, *операции пути* ожидали тело запроса в формате JSON-тело с параметрами, соответствующими атрибутам `Item`, например:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"name": "Foo",
|
||||
"description": "The pretender",
|
||||
"price": 42.0,
|
||||
"tax": 3.2
|
||||
}
|
||||
```
|
||||
|
||||
Но вы также можете объявить множество параметров тела запроса, например `item` и `user`:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="22"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial002.py!}
|
||||
```
|
||||
|
||||
В этом случае **FastAPI** заметит, что в функции есть более одного параметра тела (два параметра, которые являются моделями Pydantic).
|
||||
|
||||
Таким образом, имена параметров будут использоваться в качестве ключей (имён полей) в теле запроса, и будет ожидаться запрос следующего формата:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"item": {
|
||||
"name": "Foo",
|
||||
"description": "The pretender",
|
||||
"price": 42.0,
|
||||
"tax": 3.2
|
||||
},
|
||||
"user": {
|
||||
"username": "dave",
|
||||
"full_name": "Dave Grohl"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
!!! Внимание
|
||||
Обратите внимание, что хотя параметр `item` был объявлен таким же способом, как и раньше, теперь предпологается, что он находится внутри тела с ключом `item`.
|
||||
|
||||
|
||||
**FastAPI** сделает автоматические преобразование из запроса, так что параметр `item` получит своё конкретное содержимое, и то же самое происходит с пользователем `user`.
|
||||
|
||||
Произойдёт проверка составных данных, и создание документации в схеме OpenAPI и автоматических документах.
|
||||
|
||||
## Отдельные значения в теле запроса
|
||||
|
||||
Точно так же, как `Query` и `Path` используются для определения дополнительных данных для query и path параметров, **FastAPI** предоставляет аналогичный инструмент - `Body`.
|
||||
|
||||
Например, расширяя предыдущую модель, вы можете решить, что вам нужен еще один ключ `importance` в том же теле запроса, помимо параметров `item` и `user`.
|
||||
|
||||
Если вы объявите его без указания, какой именно объект (Path, Query, Body и .т.п.) ожидаете, то, поскольку это является простым типом данных, **FastAPI** будет считать, что это query-параметр.
|
||||
|
||||
Но вы можете указать **FastAPI** обрабатывать его, как ещё один ключ тела запроса, используя `Body`:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="23"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial003_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="23"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial003_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="24"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial003_an.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10+ non-Annotated"
|
||||
|
||||
!!! Заметка
|
||||
Рекомендуется использовать `Annotated` версию, если это возможно.
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+ non-Annotated"
|
||||
|
||||
!!! Заметка
|
||||
Рекомендуется использовать `Annotated` версию, если это возможно.
|
||||
|
||||
```Python hl_lines="22"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial003.py!}
|
||||
```
|
||||
|
||||
В этом случае, **FastAPI** будет ожидать тело запроса в формате:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"item": {
|
||||
"name": "Foo",
|
||||
"description": "The pretender",
|
||||
"price": 42.0,
|
||||
"tax": 3.2
|
||||
},
|
||||
"user": {
|
||||
"username": "dave",
|
||||
"full_name": "Dave Grohl"
|
||||
},
|
||||
"importance": 5
|
||||
}
|
||||
```
|
||||
|
||||
И всё будет работать так же - преобразование типов данных, валидация, документирование и т.д.
|
||||
|
||||
## Множество body и query параметров
|
||||
|
||||
Конечно, вы также можете объявлять query-параметры в любое время, дополнительно к любым body-параметрам.
|
||||
|
||||
Поскольку по умолчанию, отдельные значения интерпретируются как query-параметры, вам не нужно явно добавлять `Query`, вы можете просто сделать так:
|
||||
|
||||
```Python
|
||||
q: Union[str, None] = None
|
||||
```
|
||||
|
||||
Или в Python 3.10 и выше:
|
||||
|
||||
```Python
|
||||
q: str | None = None
|
||||
```
|
||||
|
||||
Например:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="27"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial004_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="27"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial004_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="28"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial004_an.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10+ non-Annotated"
|
||||
|
||||
!!! Заметка
|
||||
Рекомендуется использовать `Annotated` версию, если это возможно.
|
||||
|
||||
```Python hl_lines="25"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+ non-Annotated"
|
||||
|
||||
!!! Заметка
|
||||
Рекомендуется использовать `Annotated` версию, если это возможно.
|
||||
|
||||
```Python hl_lines="27"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial004.py!}
|
||||
```
|
||||
|
||||
!!! Информация
|
||||
`Body` также имеет все те же дополнительные параметры валидации и метаданных, как у `Query`,`Path` и других, которые вы увидите позже.
|
||||
|
||||
## Добавление одного body-параметра
|
||||
|
||||
Предположим, у вас есть только один body-параметр `item` из Pydantic модели `Item`.
|
||||
|
||||
По умолчанию, **FastAPI** ожидает получить тело запроса напрямую.
|
||||
|
||||
Но если вы хотите чтобы он ожидал JSON с ключом `item` с содержимым модели внутри, также как это происходит при объявлении дополнительных body-параметров, вы можете использовать специальный параметр `embed` у типа `Body`:
|
||||
|
||||
```Python
|
||||
item: Item = Body(embed=True)
|
||||
```
|
||||
|
||||
так же, как в этом примере:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial005_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial005_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial005_an.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10+ non-Annotated"
|
||||
|
||||
!!! Заметка
|
||||
Рекомендуется использовать `Annotated` версию, если это возможно.
|
||||
|
||||
```Python hl_lines="15"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+ non-Annotated"
|
||||
|
||||
!!! Заметка
|
||||
Рекомендуется использовать `Annotated` версию, если это возможно.
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../../docs_src/body_multiple_params/tutorial005.py!}
|
||||
```
|
||||
|
||||
В этом случае **FastAPI** будет ожидать тело запроса в формате:
|
||||
|
||||
```JSON hl_lines="2"
|
||||
{
|
||||
"item": {
|
||||
"name": "Foo",
|
||||
"description": "The pretender",
|
||||
"price": 42.0,
|
||||
"tax": 3.2
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
вместо этого:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"name": "Foo",
|
||||
"description": "The pretender",
|
||||
"price": 42.0,
|
||||
"tax": 3.2
|
||||
}
|
||||
```
|
||||
|
||||
## Резюме
|
||||
|
||||
Вы можете добавлять несколько body-параметров вашей *функции операции пути*, несмотря даже на то, что запрос может содержать только одно тело.
|
||||
|
||||
Но **FastAPI** справится с этим, предоставит правильные данные в вашей функции, а также сделает валидацию и документацию правильной схемы *операции пути*.
|
||||
|
||||
Вы также можете объявить отдельные значения для получения в рамках тела запроса.
|
||||
|
||||
И вы можете настроить **FastAPI** таким образом, чтобы включить тело запроса в ключ, даже если объявлен только один параметр.
|
||||
382
docs/ru/docs/tutorial/body-nested-models.md
Normal file
@@ -0,0 +1,382 @@
|
||||
# Body - Вложенные модели
|
||||
|
||||
С помощью **FastAPI**, вы можете определять, валидировать, документировать и использовать модели произвольной вложенности (благодаря библиотеке Pydantic).
|
||||
|
||||
## Определение полей содержащих списки
|
||||
|
||||
Вы можете определять атрибут как подтип. Например, тип `list` в Python:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="14"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial001.py!}
|
||||
```
|
||||
|
||||
Это приведёт к тому, что обьект `tags` преобразуется в список, несмотря на то что тип его элементов не объявлен.
|
||||
|
||||
## Определение полей содержащих список с определением типов его элементов
|
||||
|
||||
Однако в Python есть способ объявления списков с указанием типов для вложенных элементов:
|
||||
|
||||
### Импортируйте `List` из модуля typing
|
||||
|
||||
В Python 3.9 и выше вы можете использовать стандартный тип `list` для объявления аннотаций типов, как мы увидим ниже. 💡
|
||||
|
||||
Но в версиях Python до 3.9 (начиная с 3.6) сначала вам необходимо импортировать `List` из стандартного модуля `typing` в Python:
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial002.py!}
|
||||
```
|
||||
|
||||
### Объявление `list` с указанием типов для вложенных элементов
|
||||
|
||||
Объявление типов для элементов (внутренних типов) вложенных в такие типы как `list`, `dict`, `tuple`:
|
||||
|
||||
* Если у вас Python версии ниже чем 3.9, импортируйте их аналог из модуля `typing`
|
||||
* Передайте внутренний(ие) тип(ы) как "параметры типа", используя квадратные скобки: `[` и `]`
|
||||
|
||||
В Python версии 3.9 это будет выглядеть так:
|
||||
|
||||
```Python
|
||||
my_list: list[str]
|
||||
```
|
||||
|
||||
В версиях Python до 3.9 это будет выглядеть так:
|
||||
|
||||
```Python
|
||||
from typing import List
|
||||
|
||||
my_list: List[str]
|
||||
```
|
||||
|
||||
Это всё стандартный синтаксис Python для объявления типов.
|
||||
|
||||
Используйте этот же стандартный синтаксис для атрибутов модели с внутренними типами.
|
||||
|
||||
Таким образом, в нашем примере мы можем явно указать тип данных для поля `tags` как "список строк":
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="14"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial002_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="14"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial002.py!}
|
||||
```
|
||||
|
||||
## Типы множеств
|
||||
|
||||
Но затем мы подумали и поняли, что теги не должны повторяться и, вероятно, они должны быть уникальными строками.
|
||||
|
||||
И в Python есть специальный тип данных для множеств уникальных элементов - `set`.
|
||||
|
||||
Тогда мы может обьявить поле `tags` как множество строк:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="14"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial003_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="1 14"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial003.py!}
|
||||
```
|
||||
|
||||
С помощью этого, даже если вы получите запрос с повторяющимися данными, они будут преобразованы в множество уникальных элементов.
|
||||
|
||||
И когда вы выводите эти данные, даже если исходный набор содержал дубликаты, они будут выведены в виде множества уникальных элементов.
|
||||
|
||||
И они также будут соответствующим образом аннотированы / задокументированы.
|
||||
|
||||
## Вложенные Модели
|
||||
|
||||
У каждого атрибута Pydantic-модели есть тип.
|
||||
|
||||
Но этот тип может сам быть другой моделью Pydantic.
|
||||
|
||||
Таким образом вы можете объявлять глубоко вложенные JSON "объекты" с определёнными именами атрибутов, типами и валидацией.
|
||||
|
||||
Всё это может быть произвольно вложенным.
|
||||
|
||||
### Определение подмодели
|
||||
|
||||
Например, мы можем определить модель `Image`:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="7-9"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="9-11"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial004_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="9-11"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial004.py!}
|
||||
```
|
||||
|
||||
### Использование вложенной модели в качестве типа
|
||||
|
||||
Также мы можем использовать эту модель как тип атрибута:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial004_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial004.py!}
|
||||
```
|
||||
|
||||
Это означает, что **FastAPI** будет ожидать тело запроса, аналогичное этому:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"name": "Foo",
|
||||
"description": "The pretender",
|
||||
"price": 42.0,
|
||||
"tax": 3.2,
|
||||
"tags": ["rock", "metal", "bar"],
|
||||
"image": {
|
||||
"url": "http://example.com/baz.jpg",
|
||||
"name": "The Foo live"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Ещё раз: сделав такое объявление, с помощью **FastAPI** вы получите:
|
||||
|
||||
* Поддержку редакторов IDE (автодополнение и т.д), даже для вложенных моделей
|
||||
* Преобразование данных
|
||||
* Валидацию данных
|
||||
* Автоматическую документацию
|
||||
|
||||
## Особые типы и валидация
|
||||
|
||||
Помимо обычных простых типов, таких как `str`, `int`, `float`, и т.д. Вы можете использовать более сложные базовые типы, которые наследуются от типа `str`.
|
||||
|
||||
Чтобы увидеть все варианты, которые у вас есть, ознакомьтесь с документацией <a href="https://pydantic-docs.helpmanual.io/usage/types/" class="external-link" target="_blank">по необычным типам Pydantic</a>. Вы увидите некоторые примеры в следующей главе.
|
||||
|
||||
Например, так как в модели `Image` у нас есть поле `url`, то мы можем объявить его как тип `HttpUrl` из модуля Pydantic вместо типа `str`:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="2 8"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="4 10"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial005_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="4 10"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial005.py!}
|
||||
```
|
||||
|
||||
Строка будет проверена на соответствие допустимому URL-адресу и задокументирована в JSON схему / OpenAPI.
|
||||
|
||||
## Атрибуты, содержащие списки подмоделей
|
||||
|
||||
Вы также можете использовать модели Pydantic в качестве типов вложенных в `list`, `set` и т.д:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial006_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial006_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial006.py!}
|
||||
```
|
||||
|
||||
Такая реализация будет ожидать (конвертировать, валидировать, документировать и т.д) JSON-содержимое в следующем формате:
|
||||
|
||||
```JSON hl_lines="11"
|
||||
{
|
||||
"name": "Foo",
|
||||
"description": "The pretender",
|
||||
"price": 42.0,
|
||||
"tax": 3.2,
|
||||
"tags": [
|
||||
"rock",
|
||||
"metal",
|
||||
"bar"
|
||||
],
|
||||
"images": [
|
||||
{
|
||||
"url": "http://example.com/baz.jpg",
|
||||
"name": "The Foo live"
|
||||
},
|
||||
{
|
||||
"url": "http://example.com/dave.jpg",
|
||||
"name": "The Baz"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
!!! info "Информация"
|
||||
Заметьте, что теперь у ключа `images` есть список объектов изображений.
|
||||
|
||||
## Глубоко вложенные модели
|
||||
|
||||
Вы можете определять модели с произвольным уровнем вложенности:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="7 12 18 21 25"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial007_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="9 14 20 23 27"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial007_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="9 14 20 23 27"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial007.py!}
|
||||
```
|
||||
|
||||
!!! info "Информация"
|
||||
Заметьте, что у объекта `Offer` есть список объектов `Item`, которые, в свою очередь, могут содержать необязательный список объектов `Image`
|
||||
|
||||
## Тела с чистыми списками элементов
|
||||
|
||||
Если верхний уровень значения тела JSON-объекта представляет собой JSON `array` (в Python - `list`), вы можете объявить тип в параметре функции, так же, как в моделях Pydantic:
|
||||
|
||||
```Python
|
||||
images: List[Image]
|
||||
```
|
||||
|
||||
в Python 3.9 и выше:
|
||||
|
||||
```Python
|
||||
images: list[Image]
|
||||
```
|
||||
|
||||
например так:
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="13"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial008_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="15"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial008.py!}
|
||||
```
|
||||
|
||||
## Универсальная поддержка редактора
|
||||
|
||||
И вы получаете поддержку редактора везде.
|
||||
|
||||
Даже для элементов внутри списков:
|
||||
|
||||
<img src="/img/tutorial/body-nested-models/image01.png">
|
||||
|
||||
Вы не могли бы получить такую поддержку редактора, если бы работали напрямую с `dict`, а не с моделями Pydantic.
|
||||
|
||||
Но вы также не должны беспокоиться об этом, входящие словари автоматически конвертируются, а ваш вывод также автоматически преобразуется в формат JSON.
|
||||
|
||||
## Тела запросов с произвольными словарями (`dict` )
|
||||
|
||||
Вы также можете объявить тело запроса как `dict` с ключами определенного типа и значениями другого типа данных.
|
||||
|
||||
Без необходимости знать заранее, какие значения являются допустимыми для имён полей/атрибутов (как это было бы в случае с моделями Pydantic).
|
||||
|
||||
Это было бы полезно, если вы хотите получить ключи, которые вы еще не знаете.
|
||||
|
||||
---
|
||||
|
||||
Другой полезный случай - когда вы хотите чтобы ключи были другого типа данных, например, `int`.
|
||||
|
||||
Именно это мы сейчас и увидим здесь.
|
||||
|
||||
В этом случае вы принимаете `dict`, пока у него есть ключи типа `int` со значениями типа `float`:
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial009_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/body_nested_models/tutorial009.py!}
|
||||
```
|
||||
|
||||
!!! tip "Совет"
|
||||
Имейте в виду, что JSON поддерживает только ключи типа `str`.
|
||||
|
||||
Но Pydantic обеспечивает автоматическое преобразование данных.
|
||||
|
||||
Это значит, что даже если пользователи вашего API могут отправлять только строки в качестве ключей, при условии, что эти строки содержат целые числа, Pydantic автоматический преобразует и валидирует эти данные.
|
||||
|
||||
А `dict`, с именем `weights`, который вы получите в качестве ответа Pydantic, действительно будет иметь ключи типа `int` и значения типа `float`.
|
||||
|
||||
## Резюме
|
||||
|
||||
С помощью **FastAPI** вы получаете максимальную гибкость, предоставляемую моделями Pydantic, сохраняя при этом простоту, краткость и элегантность вашего кода.
|
||||
|
||||
И дополнительно вы получаете:
|
||||
|
||||
* Поддержку редактора (автодополнение доступно везде!)
|
||||
* Преобразование данных (также известно как парсинг / сериализация)
|
||||
* Валидацию данных
|
||||
* Документацию схемы данных
|
||||
* Автоматическую генерацию документации
|
||||
165
docs/ru/docs/tutorial/body.md
Normal file
@@ -0,0 +1,165 @@
|
||||
# Тело запроса
|
||||
|
||||
Когда вам необходимо отправить данные из клиента (допустим, браузера) в ваш API, вы отправляете их как **тело запроса**.
|
||||
|
||||
Тело **запроса** --- это данные, отправляемые клиентом в ваш API. Тело **ответа** --- это данные, которые ваш API отправляет клиенту.
|
||||
|
||||
Ваш API почти всегда отправляет тело **ответа**. Но клиентам не обязательно всегда отправлять тело **запроса**.
|
||||
|
||||
Чтобы объявить тело **запроса**, необходимо использовать модели <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a>, со всей их мощью и преимуществами.
|
||||
|
||||
!!! info "Информация"
|
||||
Чтобы отправить данные, необходимо использовать один из методов: `POST` (обычно), `PUT`, `DELETE` или `PATCH`.
|
||||
|
||||
Отправка тела с запросом `GET` имеет неопределенное поведение в спецификациях, тем не менее, оно поддерживается FastAPI только для очень сложных/экстремальных случаев использования.
|
||||
|
||||
Поскольку это не рекомендуется, интерактивная документация со Swagger UI не будет отображать информацию для тела при использовании метода GET, а промежуточные прокси-серверы могут не поддерживать такой вариант запроса.
|
||||
|
||||
## Импортирование `BaseModel` из Pydantic
|
||||
|
||||
Первое, что вам необходимо сделать, это импортировать `BaseModel` из пакета `pydantic`:
|
||||
|
||||
```Python hl_lines="4"
|
||||
{!../../../docs_src/body/tutorial001.py!}
|
||||
```
|
||||
|
||||
## Создание вашей собственной модели
|
||||
|
||||
После этого вы описываете вашу модель данных как класс, наследующий от `BaseModel`.
|
||||
|
||||
Используйте аннотации типов Python для всех атрибутов:
|
||||
|
||||
```Python hl_lines="7-11"
|
||||
{!../../../docs_src/body/tutorial001.py!}
|
||||
```
|
||||
|
||||
Также как и при описании параметров запроса, когда атрибут модели имеет значение по умолчанию, он является необязательным. Иначе он обязателен. Используйте `None`, чтобы сделать его необязательным без использования конкретных значений по умолчанию.
|
||||
|
||||
Например, модель выше описывает вот такой JSON "объект" (или словарь Python):
|
||||
|
||||
```JSON
|
||||
{
|
||||
"name": "Foo",
|
||||
"description": "An optional description",
|
||||
"price": 45.2,
|
||||
"tax": 3.5
|
||||
}
|
||||
```
|
||||
|
||||
...поскольку `description` и `tax` являются необязательными (с `None` в качестве значения по умолчанию), вот такой JSON "объект" также подходит:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"name": "Foo",
|
||||
"price": 45.2
|
||||
}
|
||||
```
|
||||
|
||||
## Объявление как параметра функции
|
||||
|
||||
Чтобы добавить параметр к вашему *обработчику*, объявите его также, как вы объявляли параметры пути или параметры запроса:
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!../../../docs_src/body/tutorial001.py!}
|
||||
```
|
||||
|
||||
...и укажите созданную модель в качестве типа параметра, `Item`.
|
||||
|
||||
## Результаты
|
||||
|
||||
Всего лишь с помощью аннотации типов Python, **FastAPI**:
|
||||
|
||||
* Читает тело запроса как JSON.
|
||||
* Приводит к соответствующим типам (если есть необходимость).
|
||||
* Проверяет корректность данных.
|
||||
* Если данные некорректны, будет возращена читаемая и понятная ошибка, показывающая что именно и в каком месте некорректно в данных.
|
||||
* Складывает полученные данные в параметр `item`.
|
||||
* Поскольку внутри функции вы объявили его с типом `Item`, то теперь у вас есть поддержка со стороны редактора (автодополнение и т.п.) для всех атрибутов и их типов.
|
||||
* Генерирует декларативное описание модели в виде <a href="https://json-schema.org" class="external-link" target="_blank">JSON Schema</a>, так что вы можете его использовать где угодно, если это имеет значение для вашего проекта.
|
||||
* Эти схемы являются частью сгенерированной схемы OpenAPI и используются для автоматического документирования <abbr title="Пользовательских интерфейсов (User Interfaces)">UI</abbr>.
|
||||
|
||||
## Автоматическое документирование
|
||||
|
||||
Схема JSON ваших моделей будет частью сгенерированной схемы OpenAPI и будет отображена в интерактивной документации API:
|
||||
|
||||
<img src="/img/tutorial/body/image01.png">
|
||||
|
||||
Также она будет указана в документации по API внутри каждой *операции пути*, в которой используются:
|
||||
|
||||
<img src="/img/tutorial/body/image02.png">
|
||||
|
||||
## Поддержка редактора
|
||||
|
||||
В вашем редакторе внутри вашей функции у вас будут подсказки по типам и автодополнение (это не будет работать, если вы получаете словарь вместо модели Pydantic):
|
||||
|
||||
<img src="/img/tutorial/body/image03.png">
|
||||
|
||||
Также вы будете получать ошибки в случае несоответствия типов:
|
||||
|
||||
<img src="/img/tutorial/body/image04.png">
|
||||
|
||||
Это не случайно, весь фреймворк построен вокруг такого дизайна.
|
||||
|
||||
И это все тщательно протестировано еще на этапе разработки дизайна, до реализации, чтобы это работало со всеми редакторами.
|
||||
|
||||
Для поддержки этого даже были внесены некоторые изменения в сам Pydantic.
|
||||
|
||||
На всех предыдущих скриншотах используется <a href="https://code.visualstudio.com" class="external-link" target="_blank">Visual Studio Code</a>.
|
||||
|
||||
Но у вас будет такая же поддержка и с <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a>, и вообще с любым редактором Python:
|
||||
|
||||
<img src="/img/tutorial/body/image05.png">
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Если вы используете <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> в качестве редактора, то вам стоит попробовать плагин <a href="https://github.com/koxudaxi/pydantic-pycharm-plugin/" class="external-link" target="_blank">Pydantic PyCharm Plugin</a>.
|
||||
|
||||
Он улучшает поддержку редактором моделей Pydantic в части:
|
||||
|
||||
* автодополнения,
|
||||
* проверки типов,
|
||||
* рефакторинга,
|
||||
* поиска,
|
||||
* инспектирования.
|
||||
|
||||
## Использование модели
|
||||
|
||||
Внутри функции вам доступны все атрибуты объекта модели напрямую:
|
||||
|
||||
```Python hl_lines="21"
|
||||
{!../../../docs_src/body/tutorial002.py!}
|
||||
```
|
||||
|
||||
## Тело запроса + параметры пути
|
||||
|
||||
Вы можете одновременно объявлять параметры пути и тело запроса.
|
||||
|
||||
**FastAPI** распознает, какие параметры функции соответствуют параметрам пути и должны быть **получены из пути**, а какие параметры функции, объявленные как модели Pydantic, должны быть **получены из тела запроса**.
|
||||
|
||||
```Python hl_lines="17-18"
|
||||
{!../../../docs_src/body/tutorial003.py!}
|
||||
```
|
||||
|
||||
## Тело запроса + параметры пути + параметры запроса
|
||||
|
||||
Вы также можете одновременно объявить параметры для **пути**, **запроса** и **тела запроса**.
|
||||
|
||||
**FastAPI** распознает каждый из них и возьмет данные из правильного источника.
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!../../../docs_src/body/tutorial004.py!}
|
||||
```
|
||||
|
||||
Параметры функции распознаются следующим образом:
|
||||
|
||||
* Если параметр также указан в **пути**, то он будет использоваться как параметр пути.
|
||||
* Если аннотация типа параметра содержит **примитивный тип** (`int`, `float`, `str`, `bool` и т.п.), он будет интерпретирован как параметр **запроса**.
|
||||
* Если аннотация типа параметра представляет собой **модель Pydantic**, он будет интерпретирован как параметр **тела запроса**.
|
||||
|
||||
!!! note "Заметка"
|
||||
FastAPI понимает, что значение параметра `q` не является обязательным, потому что имеет значение по умолчанию `= None`.
|
||||
|
||||
Аннотация `Optional` в `Optional[str]` не используется FastAPI, но помогает вашему редактору лучше понимать ваш код и обнаруживать ошибки.
|
||||
|
||||
## Без Pydantic
|
||||
|
||||
Если вы не хотите использовать модели Pydantic, вы все еще можете использовать параметры **тела запроса**. Читайте в документации раздел [Тело - Несколько параметров: Единичные значения в теле](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank}.
|
||||
84
docs/ru/docs/tutorial/cors.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# CORS (Cross-Origin Resource Sharing)
|
||||
|
||||
<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">Понятие CORS или "Cross-Origin Resource Sharing"</a> относится к ситуациям, при которых запущенный в браузере фронтенд содержит JavaScript-код, который взаимодействует с бэкендом, находящимся на другом "источнике" ("origin").
|
||||
|
||||
## Источник
|
||||
|
||||
Источник - это совокупность протокола (`http`, `https`), домена (`myapp.com`, `localhost`, `localhost.tiangolo.com`) и порта (`80`, `443`, `8080`).
|
||||
|
||||
Поэтому это три разных источника:
|
||||
|
||||
* `http://localhost`
|
||||
* `https://localhost`
|
||||
* `http://localhost:8080`
|
||||
|
||||
Даже если они все расположены в `localhost`, они используют разные протоколы и порты, а значит, являются разными источниками.
|
||||
|
||||
## Шаги
|
||||
|
||||
Допустим, у вас есть фронтенд, запущенный в браузере по адресу `http://localhost:8080`, и его JavaScript-код пытается взаимодействовать с бэкендом, запущенным по адресу `http://localhost` (поскольку мы не указали порт, браузер по умолчанию будет использовать порт `80`).
|
||||
|
||||
Затем браузер отправит бэкенду HTTP-запрос `OPTIONS`, и если бэкенд вернёт соответствующие заголовки для авторизации взаимодействия с другим источником (`http://localhost:8080`), то браузер разрешит JavaScript-коду на фронтенде отправить запрос на этот бэкенд.
|
||||
|
||||
Чтобы это работало, у бэкенда должен быть список "разрешённых источников" ("allowed origins").
|
||||
|
||||
В таком случае этот список должен содержать `http://localhost:8080`, чтобы фронтенд работал корректно.
|
||||
|
||||
## Подстановочный символ `"*"`
|
||||
|
||||
В качестве списка источников можно указать подстановочный символ `"*"` ("wildcard"), чтобы разрешить любые источники.
|
||||
|
||||
Но тогда не будут разрешены некоторые виды взаимодействия, включая всё связанное с учётными данными: куки, заголовки Authorization с Bearer-токенами наподобие тех, которые мы использовали ранее и т.п.
|
||||
|
||||
Поэтому, чтобы всё работало корректно, лучше явно указывать список разрешённых источников.
|
||||
|
||||
## Использование `CORSMiddleware`
|
||||
|
||||
Вы можете настроить этот механизм в вашем **FastAPI** приложении, используя `CORSMiddleware`.
|
||||
|
||||
* Импортируйте `CORSMiddleware`.
|
||||
* Создайте список разрешённых источников (в виде строк).
|
||||
* Добавьте его как "middleware" к вашему **FastAPI** приложению.
|
||||
|
||||
Вы также можете указать, разрешает ли ваш бэкенд использование:
|
||||
|
||||
* Учётных данных (включая заголовки Authorization, куки и т.п.).
|
||||
* Отдельных HTTP-методов (`POST`, `PUT`) или всех вместе, используя `"*"`.
|
||||
* Отдельных HTTP-заголовков или всех вместе, используя `"*"`.
|
||||
|
||||
```Python hl_lines="2 6-11 13-19"
|
||||
{!../../../docs_src/cors/tutorial001.py!}
|
||||
```
|
||||
|
||||
`CORSMiddleware` использует для параметров "запрещающие" значения по умолчанию, поэтому вам нужно явным образом разрешить использование отдельных источников, методов или заголовков, чтобы браузеры могли использовать их в кросс-доменном контексте.
|
||||
|
||||
Поддерживаются следующие аргументы:
|
||||
|
||||
* `allow_origins` - Список источников, на которые разрешено выполнять кросс-доменные запросы. Например, `['https://example.org', 'https://www.example.org']`. Можно использовать `['*']`, чтобы разрешить любые источники.
|
||||
* `allow_origin_regex` - Регулярное выражение для определения источников, на которые разрешено выполнять кросс-доменные запросы. Например, `'https://.*\.example\.org'`.
|
||||
* `allow_methods` - Список HTTP-методов, которые разрешены для кросс-доменных запросов. По умолчанию равно `['GET']`. Можно использовать `['*']`, чтобы разрешить все стандартные методы.
|
||||
* `allow_headers` - Список HTTP-заголовков, которые должны поддерживаться при кросс-доменных запросах. По умолчанию равно `[]`. Можно использовать `['*']`, чтобы разрешить все заголовки. Заголовки `Accept`, `Accept-Language`, `Content-Language` и `Content-Type` всегда разрешены для <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests" class="external-link" rel="noopener" target="_blank">простых CORS-запросов</a>.
|
||||
* `allow_credentials` - указывает, что куки разрешены в кросс-доменных запросах. По умолчанию равно `False`. Также, `allow_origins` нельзя присвоить `['*']`, если разрешено использование учётных данных. В таком случае должен быть указан список источников.
|
||||
* `expose_headers` - Указывает любые заголовки ответа, которые должны быть доступны браузеру. По умолчанию равно `[]`.
|
||||
* `max_age` - Устанавливает максимальное время в секундах, в течение которого браузер кэширует CORS-ответы. По умолчанию равно `600`.
|
||||
|
||||
`CORSMiddleware` отвечает на два типа HTTP-запросов...
|
||||
|
||||
### CORS-запросы с предварительной проверкой
|
||||
|
||||
Это любые `OPTIONS` запросы с заголовками `Origin` и `Access-Control-Request-Method`.
|
||||
|
||||
В этом случае middleware перехватит входящий запрос и отправит соответствующие CORS-заголовки в ответе, а также ответ `200` или `400` в информационных целях.
|
||||
|
||||
### Простые запросы
|
||||
|
||||
Любые запросы с заголовком `Origin`. В этом случае middleware передаст запрос дальше как обычно, но добавит соответствующие CORS-заголовки к ответу.
|
||||
|
||||
## Больше информации
|
||||
|
||||
Для получения более подробной информации о <abbr title="Cross-Origin Resource Sharing">CORS</abbr>, обратитесь к <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" class="external-link" target="_blank">Документации CORS от Mozilla</a>.
|
||||
|
||||
!!! note "Технические детали"
|
||||
Вы также можете использовать `from starlette.middleware.cors import CORSMiddleware`.
|
||||
|
||||
**FastAPI** предоставляет несколько middleware в `fastapi.middleware` только для вашего удобства как разработчика. Но большинство доступных middleware взяты напрямую из Starlette.
|
||||
112
docs/ru/docs/tutorial/debugging.md
Normal file
@@ -0,0 +1,112 @@
|
||||
# Отладка
|
||||
|
||||
Вы можете подключить отладчик в своем редакторе, например, в Visual Studio Code или PyCharm.
|
||||
|
||||
## Вызов `uvicorn`
|
||||
|
||||
В вашем FastAPI приложении, импортируйте и вызовите `uvicorn` напрямую:
|
||||
|
||||
```Python hl_lines="1 15"
|
||||
{!../../../docs_src/debugging/tutorial001.py!}
|
||||
```
|
||||
|
||||
### Описание `__name__ == "__main__"`
|
||||
|
||||
Главная цель использования `__name__ == "__main__"` в том, чтобы код выполнялся при запуске файла с помощью:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python myapp.py
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
но не вызывался, когда другой файл импортирует это, например::
|
||||
|
||||
```Python
|
||||
from myapp import app
|
||||
```
|
||||
|
||||
#### Больше деталей
|
||||
|
||||
Давайте назовём ваш файл `myapp.py`.
|
||||
|
||||
Если вы запустите его с помощью:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python myapp.py
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
то встроенная переменная `__name__`, автоматически создаваемая Python в вашем файле, будет иметь значение строкового типа `"__main__"`.
|
||||
|
||||
Тогда выполнится условие и эта часть кода:
|
||||
|
||||
```Python
|
||||
uvicorn.run(app, host="0.0.0.0", port=8000)
|
||||
```
|
||||
|
||||
будет запущена.
|
||||
|
||||
---
|
||||
|
||||
Но этого не произойдет, если вы импортируете этот модуль (файл).
|
||||
|
||||
Таким образом, если у вас есть файл `importer.py` с таким импортом:
|
||||
|
||||
```Python
|
||||
from myapp import app
|
||||
|
||||
# Some more code
|
||||
```
|
||||
|
||||
то автоматическая создаваемая внутри файла `myapp.py` переменная `__name__` будет иметь значение отличающееся от `"__main__"`.
|
||||
|
||||
Следовательно, строка:
|
||||
|
||||
```Python
|
||||
uvicorn.run(app, host="0.0.0.0", port=8000)
|
||||
```
|
||||
|
||||
не будет выполнена.
|
||||
|
||||
!!! Информация
|
||||
Для получения дополнительной информации, ознакомьтесь с <a href="https://docs.python.org/3/library/__main__.html" class="external-link" target="_blank">официальной документацией Python</a>.
|
||||
|
||||
## Запуск вашего кода с помощью отладчика
|
||||
|
||||
Так как вы запускаете сервер Uvicorn непосредственно из вашего кода, вы можете вызвать Python программу (ваше FastAPI приложение) напрямую из отладчика.
|
||||
|
||||
---
|
||||
|
||||
Например, в Visual Studio Code вы можете выполнить следующие шаги:
|
||||
|
||||
* Перейдите на панель "Debug".
|
||||
* Выберите "Add configuration...".
|
||||
* Выберите "Python"
|
||||
* Запустите отладчик "`Python: Current File (Integrated Terminal)`".
|
||||
|
||||
Это запустит сервер с вашим **FastAPI** кодом, остановится на точках останова, и т.д.
|
||||
|
||||
Вот как это может выглядеть:
|
||||
|
||||
<img src="/img/tutorial/debugging/image01.png">
|
||||
|
||||
---
|
||||
|
||||
Если используете Pycharm, вы можете выполнить следующие шаги:
|
||||
|
||||
* Открыть "Run" меню.
|
||||
* Выбрать опцию "Debug...".
|
||||
* Затем в появившемся контекстном меню.
|
||||
* Выбрать файл для отладки (в данном случае, `main.py`).
|
||||
|
||||
Это запустит сервер с вашим **FastAPI** кодом, остановится на точках останова, и т.д.
|
||||
|
||||
Вот как это может выглядеть:
|
||||
|
||||
<img src="/img/tutorial/debugging/image02.png">
|
||||
252
docs/ru/docs/tutorial/extra-models.md
Normal file
@@ -0,0 +1,252 @@
|
||||
# Дополнительные модели
|
||||
|
||||
В продолжение прошлого примера будет уже обычным делом иметь несколько связанных между собой моделей.
|
||||
|
||||
Это особенно применимо в случае моделей пользователя, потому что:
|
||||
|
||||
* **Модель для ввода** должна иметь возможность содержать пароль.
|
||||
* **Модель для вывода** не должна содержать пароль.
|
||||
* **Модель для базы данных**, возможно, должна содержать хэшированный пароль.
|
||||
|
||||
!!! danger "Внимание"
|
||||
Никогда не храните пароли пользователей в чистом виде. Всегда храните "безопасный хэш", который вы затем сможете проверить.
|
||||
|
||||
Если вам это не знакомо, вы можете узнать про "хэш пароля" в [главах о безопасности](security/simple-oauth2.md#password-hashing){.internal-link target=_blank}.
|
||||
|
||||
## Множественные модели
|
||||
|
||||
Ниже изложена основная идея того, как могут выглядеть эти модели с полями для паролей, а также описаны места, где они используются:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="7 9 14 20 22 27-28 31-33 38-39"
|
||||
{!> ../../../docs_src/extra_models/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="9 11 16 22 24 29-30 33-35 40-41"
|
||||
{!> ../../../docs_src/extra_models/tutorial001.py!}
|
||||
```
|
||||
|
||||
### Про `**user_in.dict()`
|
||||
|
||||
#### `.dict()` из Pydantic
|
||||
|
||||
`user_in` - это Pydantic-модель класса `UserIn`.
|
||||
|
||||
У Pydantic-моделей есть метод `.dict()`, который возвращает `dict` с данными модели.
|
||||
|
||||
Поэтому, если мы создадим Pydantic-объект `user_in` таким способом:
|
||||
|
||||
```Python
|
||||
user_in = UserIn(username="john", password="secret", email="john.doe@example.com")
|
||||
```
|
||||
|
||||
и затем вызовем:
|
||||
|
||||
```Python
|
||||
user_dict = user_in.dict()
|
||||
```
|
||||
|
||||
то теперь у нас есть `dict` с данными модели в переменной `user_dict` (это `dict` вместо объекта Pydantic-модели).
|
||||
|
||||
И если мы вызовем:
|
||||
|
||||
```Python
|
||||
print(user_dict)
|
||||
```
|
||||
|
||||
мы можем получить `dict` с такими данными:
|
||||
|
||||
```Python
|
||||
{
|
||||
'username': 'john',
|
||||
'password': 'secret',
|
||||
'email': 'john.doe@example.com',
|
||||
'full_name': None,
|
||||
}
|
||||
```
|
||||
|
||||
#### Распаковка `dict`
|
||||
|
||||
Если мы возьмём `dict` наподобие `user_dict` и передадим его в функцию (или класс), используя `**user_dict`, Python распакует его. Он передаст ключи и значения `user_dict` напрямую как аргументы типа ключ-значение.
|
||||
|
||||
Поэтому, продолжая описанный выше пример с `user_dict`, написание такого кода:
|
||||
|
||||
```Python
|
||||
UserInDB(**user_dict)
|
||||
```
|
||||
|
||||
Будет работать так же, как примерно такой код:
|
||||
|
||||
```Python
|
||||
UserInDB(
|
||||
username="john",
|
||||
password="secret",
|
||||
email="john.doe@example.com",
|
||||
full_name=None,
|
||||
)
|
||||
```
|
||||
|
||||
Или, если для большей точности мы напрямую используем `user_dict` с любым потенциальным содержимым, то этот пример будет выглядеть так:
|
||||
|
||||
```Python
|
||||
UserInDB(
|
||||
username = user_dict["username"],
|
||||
password = user_dict["password"],
|
||||
email = user_dict["email"],
|
||||
full_name = user_dict["full_name"],
|
||||
)
|
||||
```
|
||||
|
||||
#### Pydantic-модель из содержимого другой модели
|
||||
|
||||
Как в примере выше мы получили `user_dict` из `user_in.dict()`, этот код:
|
||||
|
||||
```Python
|
||||
user_dict = user_in.dict()
|
||||
UserInDB(**user_dict)
|
||||
```
|
||||
|
||||
будет равнозначен такому:
|
||||
|
||||
```Python
|
||||
UserInDB(**user_in.dict())
|
||||
```
|
||||
|
||||
...потому что `user_in.dict()` - это `dict`, и затем мы указываем, чтобы Python его "распаковал", когда передаём его в `UserInDB` и ставим перед ним `**`.
|
||||
|
||||
Таким образом мы получаем Pydantic-модель на основе данных из другой Pydantic-модели.
|
||||
|
||||
#### Распаковка `dict` и дополнительные именованные аргументы
|
||||
|
||||
И затем, если мы добавим дополнительный именованный аргумент `hashed_password=hashed_password` как здесь:
|
||||
|
||||
```Python
|
||||
UserInDB(**user_in.dict(), hashed_password=hashed_password)
|
||||
```
|
||||
|
||||
... то мы получим что-то подобное:
|
||||
|
||||
```Python
|
||||
UserInDB(
|
||||
username = user_dict["username"],
|
||||
password = user_dict["password"],
|
||||
email = user_dict["email"],
|
||||
full_name = user_dict["full_name"],
|
||||
hashed_password = hashed_password,
|
||||
)
|
||||
```
|
||||
|
||||
!!! warning "Предупреждение"
|
||||
Цель использованных в примере вспомогательных функций - не более чем демонстрация возможных операций с данными, но, конечно, они не обеспечивают настоящую безопасность.
|
||||
|
||||
## Сократите дублирование
|
||||
|
||||
Сокращение дублирования кода - это одна из главных идей **FastAPI**.
|
||||
|
||||
Поскольку дублирование кода повышает риск появления багов, проблем с безопасностью, проблем десинхронизации кода (когда вы обновляете код в одном месте, но не обновляете в другом), и т.д.
|
||||
|
||||
А все описанные выше модели используют много общих данных и дублируют названия атрибутов и типов.
|
||||
|
||||
Мы можем это улучшить.
|
||||
|
||||
Мы можем определить модель `UserBase`, которая будет базовой для остальных моделей. И затем мы можем создать подклассы этой модели, которые будут наследовать её атрибуты (объявления типов, валидацию, и т.п.).
|
||||
|
||||
Все операции конвертации, валидации, документации, и т.п. будут по-прежнему работать нормально.
|
||||
|
||||
В этом случае мы можем определить только различия между моделями (с `password` в чистом виде, с `hashed_password` и без пароля):
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="7 13-14 17-18 21-22"
|
||||
{!> ../../../docs_src/extra_models/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="9 15-16 19-20 23-24"
|
||||
{!> ../../../docs_src/extra_models/tutorial002.py!}
|
||||
```
|
||||
|
||||
## `Union` или `anyOf`
|
||||
|
||||
Вы можете определить ответ как `Union` из двух типов. Это означает, что ответ должен соответствовать одному из них.
|
||||
|
||||
Он будет определён в OpenAPI как `anyOf`.
|
||||
|
||||
Для этого используйте стандартные аннотации типов в Python <a href="https://docs.python.org/3/library/typing.html#typing.Union" class="external-link" target="_blank">`typing.Union`</a>:
|
||||
|
||||
!!! note "Примечание"
|
||||
При объявлении <a href="https://pydantic-docs.helpmanual.io/usage/types/#unions" class="external-link" target="_blank">`Union`</a>, сначала указывайте наиболее детальные типы, затем менее детальные. В примере ниже более детальный `PlaneItem` стоит перед `CarItem` в `Union[PlaneItem, CarItem]`.
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="1 14-15 18-20 33"
|
||||
{!> ../../../docs_src/extra_models/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="1 14-15 18-20 33"
|
||||
{!> ../../../docs_src/extra_models/tutorial003.py!}
|
||||
```
|
||||
|
||||
### `Union` в Python 3.10
|
||||
|
||||
В этом примере мы передаём `Union[PlaneItem, CarItem]` в качестве значения аргумента `response_model`.
|
||||
|
||||
Поскольку мы передаём его как **значение аргумента** вместо того, чтобы поместить его в **аннотацию типа**, нам придётся использовать `Union` даже в Python 3.10.
|
||||
|
||||
Если оно было бы указано в аннотации типа, то мы могли бы использовать вертикальную черту как в примере:
|
||||
|
||||
```Python
|
||||
some_variable: PlaneItem | CarItem
|
||||
```
|
||||
|
||||
Но если мы помещаем его в `response_model=PlaneItem | CarItem` мы получим ошибку, потому что Python попытается произвести **некорректную операцию** между `PlaneItem` и `CarItem` вместо того, чтобы интерпретировать это как аннотацию типа.
|
||||
|
||||
## Список моделей
|
||||
|
||||
Таким же образом вы можете определять ответы как списки объектов.
|
||||
|
||||
Для этого используйте `typing.List` из стандартной библиотеки Python (или просто `list` в Python 3.9 и выше):
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!> ../../../docs_src/extra_models/tutorial004_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="1 20"
|
||||
{!> ../../../docs_src/extra_models/tutorial004.py!}
|
||||
```
|
||||
|
||||
## Ответ с произвольным `dict`
|
||||
|
||||
Вы также можете определить ответ, используя произвольный одноуровневый `dict` и определяя только типы ключей и значений без использования Pydantic-моделей.
|
||||
|
||||
Это полезно, если вы заранее не знаете корректных названий полей/атрибутов (которые будут нужны при использовании Pydantic-модели).
|
||||
|
||||
В этом случае вы можете использовать `typing.Dict` (или просто `dict` в Python 3.9 и выше):
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!> ../../../docs_src/extra_models/tutorial005_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="1 8"
|
||||
{!> ../../../docs_src/extra_models/tutorial005.py!}
|
||||
```
|
||||
|
||||
## Резюме
|
||||
|
||||
Используйте несколько Pydantic-моделей и свободно применяйте наследование для каждой из них.
|
||||
|
||||
Вам не обязательно иметь единственную модель данных для каждой сущности, если эта сущность должна иметь возможность быть в разных "состояниях". Как в случае с "сущностью" пользователя, у которого есть состояния с полями `password`, `password_hash` и без пароля.
|
||||
333
docs/ru/docs/tutorial/first-steps.md
Normal file
@@ -0,0 +1,333 @@
|
||||
# Первые шаги
|
||||
|
||||
Самый простой FastAPI файл может выглядеть так:
|
||||
|
||||
```Python
|
||||
{!../../../docs_src/first_steps/tutorial001.py!}
|
||||
```
|
||||
|
||||
Скопируйте в файл `main.py`.
|
||||
|
||||
Запустите сервер в режиме реального времени:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --reload
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
<span style="color: green;">INFO</span>: Started reloader process [28720]
|
||||
<span style="color: green;">INFO</span>: Started server process [28722]
|
||||
<span style="color: green;">INFO</span>: Waiting for application startup.
|
||||
<span style="color: green;">INFO</span>: Application startup complete.
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
!!! note "Технические детали"
|
||||
Команда `uvicorn main:app` обращается к:
|
||||
|
||||
* `main`: файл `main.py` (модуль Python).
|
||||
* `app`: объект, созданный внутри файла `main.py` в строке `app = FastAPI()`.
|
||||
* `--reload`: перезапускает сервер после изменения кода. Используйте только для разработки.
|
||||
|
||||
В окне вывода появится следующая строка:
|
||||
|
||||
```hl_lines="4"
|
||||
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
Эта строка показывает URL-адрес, по которому приложение доступно на локальной машине.
|
||||
|
||||
### Проверьте
|
||||
|
||||
Откройте браузер по адресу: <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>.
|
||||
|
||||
Вы увидите JSON-ответ следующего вида:
|
||||
|
||||
```JSON
|
||||
{"message": "Hello World"}
|
||||
```
|
||||
|
||||
### Интерактивная документация API
|
||||
|
||||
Перейдите по адресу: <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||
|
||||
Вы увидите автоматически сгенерированную, интерактивную документацию по API (предоставленную <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
|
||||
|
||||

|
||||
|
||||
### Альтернативная документация API
|
||||
|
||||
Теперь перейдите по адресу <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
|
||||
|
||||
Вы увидите альтернативную автоматически сгенерированную документацию (предоставленную <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>):
|
||||
|
||||

|
||||
|
||||
### OpenAPI
|
||||
|
||||
**FastAPI** генерирует "схему" всего API, используя стандарт **OpenAPI**.
|
||||
|
||||
#### "Схема"
|
||||
|
||||
"Схема" - это определение или описание чего-либо. Не код, реализующий это, а только абстрактное описание.
|
||||
|
||||
#### API "схема"
|
||||
|
||||
<a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> - это спецификация, которая определяет, как описывать схему API.
|
||||
|
||||
Определение схемы содержит пути (paths) API, их параметры и т.п.
|
||||
|
||||
#### "Схема" данных
|
||||
|
||||
Термин "схема" также может относиться к формату или структуре некоторых данных, например, JSON.
|
||||
|
||||
Тогда, подразумеваются атрибуты JSON, их типы данных и т.п.
|
||||
|
||||
#### OpenAPI и JSON Schema
|
||||
|
||||
OpenAPI описывает схему API. Эта схема содержит определения (или "схемы") данных, отправляемых и получаемых API. Для описания структуры данных в JSON используется стандарт **JSON Schema**.
|
||||
|
||||
#### Рассмотрим `openapi.json`
|
||||
|
||||
Если Вас интересует, как выглядит исходная схема OpenAPI, то FastAPI автоматически генерирует JSON-схему со всеми описаниями API.
|
||||
|
||||
Можете посмотреть здесь: <a href="http://127.0.0.1:8000/openapi.json" class="external-link" target="_blank">http://127.0.0.1:8000/openapi.json</a>.
|
||||
|
||||
Вы увидите примерно такой JSON:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"openapi": "3.0.2",
|
||||
"info": {
|
||||
"title": "FastAPI",
|
||||
"version": "0.1.0"
|
||||
},
|
||||
"paths": {
|
||||
"/items/": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
|
||||
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
#### Для чего нужен OpenAPI
|
||||
|
||||
Схема OpenAPI является основой для обеих систем интерактивной документации.
|
||||
|
||||
Существуют десятки альтернативных инструментов, основанных на OpenAPI. Вы можете легко добавить любой из них к **FastAPI** приложению.
|
||||
|
||||
Вы также можете использовать OpenAPI для автоматической генерации кода для клиентов, которые взаимодействуют с API. Например, для фронтенд-, мобильных или IoT-приложений.
|
||||
|
||||
## Рассмотрим поэтапно
|
||||
|
||||
### Шаг 1: импортируйте `FastAPI`
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!../../../docs_src/first_steps/tutorial001.py!}
|
||||
```
|
||||
|
||||
`FastAPI` это класс в Python, который предоставляет всю функциональность для API.
|
||||
|
||||
!!! note "Технические детали"
|
||||
`FastAPI` это класс, который наследуется непосредственно от `Starlette`.
|
||||
|
||||
Вы можете использовать всю функциональность <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> в `FastAPI`.
|
||||
|
||||
### Шаг 2: создайте экземпляр `FastAPI`
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!../../../docs_src/first_steps/tutorial001.py!}
|
||||
```
|
||||
|
||||
Переменная `app` является экземпляром класса `FastAPI`.
|
||||
|
||||
Это единая точка входа для создания и взаимодействия с API.
|
||||
|
||||
Именно к этой переменной `app` обращается `uvicorn` в команде:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --reload
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Если создать такое приложение:
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!../../../docs_src/first_steps/tutorial002.py!}
|
||||
```
|
||||
|
||||
И поместить его в `main.py`, тогда вызов `uvicorn` будет таким:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:my_awesome_api --reload
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### Шаг 3: определите *операцию пути (path operation)*
|
||||
|
||||
#### Путь (path)
|
||||
|
||||
"Путь" это часть URL, после первого символа `/`, следующего за именем домена.
|
||||
|
||||
Для URL:
|
||||
|
||||
```
|
||||
https://example.com/items/foo
|
||||
```
|
||||
|
||||
...путь выглядит так:
|
||||
|
||||
```
|
||||
/items/foo
|
||||
```
|
||||
|
||||
!!! info "Дополнительная иформация"
|
||||
Термин "path" также часто называется "endpoint" или "route".
|
||||
|
||||
При создании API, "путь" является основным способом разделения "задач" и "ресурсов".
|
||||
|
||||
#### Операция (operation)
|
||||
|
||||
"Операция" это один из "методов" HTTP.
|
||||
|
||||
Таких, как:
|
||||
|
||||
* `POST`
|
||||
* `GET`
|
||||
* `PUT`
|
||||
* `DELETE`
|
||||
|
||||
...и более экзотических:
|
||||
|
||||
* `OPTIONS`
|
||||
* `HEAD`
|
||||
* `PATCH`
|
||||
* `TRACE`
|
||||
|
||||
По протоколу HTTP можно обращаться к каждому пути, используя один (или несколько) из этих "методов".
|
||||
|
||||
---
|
||||
|
||||
При создании API принято использовать конкретные HTTP-методы для выполнения определенных действий.
|
||||
|
||||
Обычно используют:
|
||||
|
||||
* `POST`: создать данные.
|
||||
* `GET`: прочитать.
|
||||
* `PUT`: изменить (обновить).
|
||||
* `DELETE`: удалить.
|
||||
|
||||
В OpenAPI каждый HTTP метод называется "**операция**".
|
||||
|
||||
Мы также будем придерживаться этого термина.
|
||||
|
||||
#### Определите *декоратор операции пути (path operation decorator)*
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!../../../docs_src/first_steps/tutorial001.py!}
|
||||
```
|
||||
|
||||
Декоратор `@app.get("/")` указывает **FastAPI**, что функция, прямо под ним, отвечает за обработку запросов, поступающих по адресу:
|
||||
|
||||
* путь `/`
|
||||
* использующих <abbr title="HTTP GET метод"><code>get</code> операцию</abbr>
|
||||
|
||||
!!! info "`@decorator` Дополнительная информация"
|
||||
Синтаксис `@something` в Python называется "декоратор".
|
||||
|
||||
Вы помещаете его над функцией. Как красивую декоративную шляпу (думаю, что оттуда и происходит этот термин).
|
||||
|
||||
"Декоратор" принимает функцию ниже и выполняет с ней какое-то действие.
|
||||
|
||||
В нашем случае, этот декоратор сообщает **FastAPI**, что функция ниже соответствует **пути** `/` и **операции** `get`.
|
||||
|
||||
Это и есть "**декоратор операции пути**".
|
||||
|
||||
Можно также использовать операции:
|
||||
|
||||
* `@app.post()`
|
||||
* `@app.put()`
|
||||
* `@app.delete()`
|
||||
|
||||
И более экзотические:
|
||||
|
||||
* `@app.options()`
|
||||
* `@app.head()`
|
||||
* `@app.patch()`
|
||||
* `@app.trace()`
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Вы можете использовать каждую операцию (HTTP-метод) по своему усмотрению.
|
||||
|
||||
**FastAPI** не навязывает определенного значения для каждого метода.
|
||||
|
||||
Информация здесь представлена как рекомендация, а не требование.
|
||||
|
||||
Например, при использовании GraphQL обычно все действия выполняются только с помощью POST операций.
|
||||
|
||||
### Шаг 4: определите **функцию операции пути**
|
||||
|
||||
Вот "**функция операции пути**":
|
||||
|
||||
* **путь**: `/`.
|
||||
* **операция**: `get`.
|
||||
* **функция**: функция ниже "декоратора" (ниже `@app.get("/")`).
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!../../../docs_src/first_steps/tutorial001.py!}
|
||||
```
|
||||
|
||||
Это обычная Python функция.
|
||||
|
||||
**FastAPI** будет вызывать её каждый раз при получении `GET` запроса к URL "`/`".
|
||||
|
||||
В данном случае это асинхронная функция.
|
||||
|
||||
---
|
||||
|
||||
Вы также можете определить ее как обычную функцию вместо `async def`:
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!../../../docs_src/first_steps/tutorial003.py!}
|
||||
```
|
||||
|
||||
!!! note "Технические детали"
|
||||
Если не знаете в чём разница, посмотрите [Конкурентность: *"Нет времени?"*](../async.md#in-a-hurry){.internal-link target=_blank}.
|
||||
|
||||
### Шаг 5: верните результат
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!../../../docs_src/first_steps/tutorial001.py!}
|
||||
```
|
||||
|
||||
Вы можете вернуть `dict`, `list`, отдельные значения `str`, `int` и т.д.
|
||||
|
||||
Также можно вернуть модели Pydantic (рассмотрим это позже).
|
||||
|
||||
Многие объекты и модели будут автоматически преобразованы в JSON (включая ORM). Пробуйте использовать другие объекты, которые предпочтительней для Вас, вероятно, они уже поддерживаются.
|
||||
|
||||
## Резюме
|
||||
|
||||
* Импортируем `FastAPI`.
|
||||
* Создаём экземпляр `app`.
|
||||
* Пишем **декоратор операции пути** (такой как `@app.get("/")`).
|
||||
* Пишем **функцию операции пути** (`def root(): ...`).
|
||||
* Запускаем сервер в режиме разработки (`uvicorn main:app --reload`).
|
||||
80
docs/ru/docs/tutorial/index.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# Учебник - Руководство пользователя - Введение
|
||||
|
||||
В этом руководстве шаг за шагом показано, как использовать **FastApi** с большинством его функций.
|
||||
|
||||
Каждый раздел постепенно основывается на предыдущих, но он структурирован по отдельным темам, так что вы можете перейти непосредственно к конкретной теме для решения ваших конкретных потребностей в API.
|
||||
|
||||
Он также создан для использования в качестве будущего справочника.
|
||||
|
||||
Так что вы можете вернуться и посмотреть именно то, что вам нужно.
|
||||
|
||||
## Запустите код
|
||||
|
||||
Все блоки кода можно копировать и использовать напрямую (на самом деле это проверенные файлы Python).
|
||||
|
||||
Чтобы запустить любой из примеров, скопируйте код в файл `main.py` и запустите `uvicorn` с параметрами:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --reload
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
<span style="color: green;">INFO</span>: Started reloader process [28720]
|
||||
<span style="color: green;">INFO</span>: Started server process [28722]
|
||||
<span style="color: green;">INFO</span>: Waiting for application startup.
|
||||
<span style="color: green;">INFO</span>: Application startup complete.
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
**НАСТОЯТЕЛЬНО рекомендуется**, чтобы вы написали или скопировали код, отредактировали его и запустили локально.
|
||||
|
||||
Использование кода в вашем редакторе — это то, что действительно показывает вам преимущества FastAPI, видя, как мало кода вам нужно написать, все проверки типов, автодополнение и т.д.
|
||||
|
||||
---
|
||||
|
||||
## Установка FastAPI
|
||||
|
||||
Первый шаг — установить FastAPI.
|
||||
|
||||
Для руководства вы, возможно, захотите установить его со всеми дополнительными зависимостями и функциями:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "fastapi[all]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
...это также включает `uvicorn`, который вы можете использовать в качестве сервера, который запускает ваш код.
|
||||
|
||||
!!! note "Технические детали"
|
||||
Вы также можете установить его по частям.
|
||||
|
||||
Это то, что вы, вероятно, сделаете, когда захотите развернуть свое приложение в рабочей среде:
|
||||
|
||||
```
|
||||
pip install fastapi
|
||||
```
|
||||
|
||||
Также установите `uvicorn` для работы в качестве сервера:
|
||||
|
||||
```
|
||||
pip install "uvicorn[standard]"
|
||||
```
|
||||
|
||||
И то же самое для каждой из необязательных зависимостей, которые вы хотите использовать.
|
||||
|
||||
## Продвинутое руководство пользователя
|
||||
|
||||
Существует также **Продвинутое руководство пользователя**, которое вы сможете прочитать после руководства **Учебник - Руководство пользователя**.
|
||||
|
||||
**Продвинутое руководство пользователя** основано на этом, использует те же концепции и учит вас некоторым дополнительным функциям.
|
||||
|
||||
Но вы должны сначала прочитать **Учебник - Руководство пользователя** (то, что вы читаете прямо сейчас).
|
||||
|
||||
Он разработан таким образом, что вы можете создать полноценное приложение, используя только **Учебник - Руководство пользователя**, а затем расширить его различными способами, в зависимости от ваших потребностей, используя некоторые дополнительные идеи из **Продвинутого руководства пользователя**.
|
||||
111
docs/ru/docs/tutorial/metadata.md
Normal file
@@ -0,0 +1,111 @@
|
||||
# URL-адреса метаданных и документации
|
||||
|
||||
Вы можете настроить несколько конфигураций метаданных в вашем **FastAPI** приложении.
|
||||
|
||||
## Метаданные для API
|
||||
|
||||
Вы можете задать следующие поля, которые используются в спецификации OpenAPI и в UI автоматической документации API:
|
||||
|
||||
| Параметр | Тип | Описание |
|
||||
|------------|--|-------------|
|
||||
| `title` | `str` | Заголовок API. |
|
||||
| `description` | `str` | Краткое описание API. Может быть использован Markdown. |
|
||||
| `version` | `string` | Версия API. Версия вашего собственного приложения, а не OpenAPI. К примеру `2.5.0`. |
|
||||
| `terms_of_service` | `str` | Ссылка к условиям пользования API. Если указано, то это должен быть URL-адрес. |
|
||||
| `contact` | `dict` | Контактная информация для открытого API. Может содержать несколько полей. <details><summary>поля <code>contact</code></summary><table><thead><tr><th>Параметр</th><th>Тип</th><th>Описание</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td>Идентификационное имя контактного лица/организации.</td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>URL указывающий на контактную информацию. ДОЛЖЕН быть в формате URL.</td></tr><tr><td><code>email</code></td><td><code>str</code></td><td>Email адрес контактного лица/организации. ДОЛЖЕН быть в формате email адреса.</td></tr></tbody></table></details> |
|
||||
| `license_info` | `dict` | Информация о лицензии открытого API. Может содержать несколько полей. <details><summary>поля <code>license_info</code></summary><table><thead><tr><th>Параметр</th><th>Тип</th><th>Описание</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td><strong>ОБЯЗАТЕЛЬНО</strong> (если установлен параметр <code>license_info</code>). Название лицензии, используемой для API</td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>URL, указывающий на лицензию, используемую для API. ДОЛЖЕН быть в формате URL.</td></tr></tbody></table></details> |
|
||||
|
||||
Вы можете задать их следующим образом:
|
||||
|
||||
```Python hl_lines="3-16 19-31"
|
||||
{!../../../docs_src/metadata/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Вы можете использовать Markdown в поле `description`, и оно будет отображено в выводе.
|
||||
|
||||
С этой конфигурацией автоматическая документация API будут выглядеть так:
|
||||
|
||||
<img src="/img/tutorial/metadata/image01.png">
|
||||
|
||||
## Метаданные для тегов
|
||||
|
||||
Вы также можете добавить дополнительные метаданные для различных тегов, используемых для группировки ваших операций пути с помощью параметра `openapi_tags`.
|
||||
|
||||
Он принимает список, содержащий один словарь для каждого тега.
|
||||
|
||||
Каждый словарь может содержать в себе:
|
||||
|
||||
* `name` (**обязательно**): `str`-значение с тем же именем тега, которое вы используете в параметре `tags` в ваших *операциях пути* и `APIRouter`ах.
|
||||
* `description`: `str`-значение с кратким описанием для тега. Может содержать Markdown и будет отображаться в UI документации.
|
||||
* `externalDocs`: `dict`-значение описывающее внешнюю документацию. Включает в себя:
|
||||
* `description`: `str`-значение с кратким описанием для внешней документации.
|
||||
* `url` (**обязательно**): `str`-значение с URL-адресом для внешней документации.
|
||||
|
||||
### Создание метаданных для тегов
|
||||
|
||||
Давайте попробуем сделать это на примере с тегами для `users` и `items`.
|
||||
|
||||
Создайте метаданные для ваших тегов и передайте их в параметре `openapi_tags`:
|
||||
|
||||
```Python hl_lines="3-16 18"
|
||||
{!../../../docs_src/metadata/tutorial004.py!}
|
||||
```
|
||||
|
||||
Помните, что вы можете использовать Markdown внутри описания, к примеру "login" будет отображен жирным шрифтом (**login**) и "fancy" будет отображаться курсивом (_fancy_).
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Вам необязательно добавлять метаданные для всех используемых тегов
|
||||
|
||||
### Используйте собственные теги
|
||||
Используйте параметр `tags` с вашими *операциями пути* (и `APIRouter`ами), чтобы присвоить им различные теги:
|
||||
|
||||
```Python hl_lines="21 26"
|
||||
{!../../../docs_src/metadata/tutorial004.py!}
|
||||
```
|
||||
|
||||
!!! info "Дополнительная информация"
|
||||
Узнайте больше о тегах в [Конфигурации операции пути](../path-operation-configuration/#tags){.internal-link target=_blank}.
|
||||
|
||||
### Проверьте документацию
|
||||
|
||||
Теперь, если вы проверите документацию, вы увидите всю дополнительную информацию:
|
||||
|
||||
<img src="/img/tutorial/metadata/image02.png">
|
||||
|
||||
### Порядок расположения тегов
|
||||
|
||||
Порядок расположения словарей метаданных для каждого тега определяет также порядок, отображаемый в документах UI
|
||||
|
||||
К примеру, несмотря на то, что `users` будут идти после `items` в алфавитном порядке, они отображаются раньше, потому что мы добавляем свои метаданные в качестве первого словаря в списке.
|
||||
|
||||
## URL-адреса OpenAPI
|
||||
|
||||
По умолчанию схема OpenAPI отображена по адресу `/openapi.json`.
|
||||
|
||||
Но вы можете изменить это с помощью параметра `openapi_url`.
|
||||
|
||||
К примеру, чтобы задать её отображение по адресу `/api/v1/openapi.json`:
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!../../../docs_src/metadata/tutorial002.py!}
|
||||
```
|
||||
|
||||
Если вы хотите отключить схему OpenAPI полностью, вы можете задать `openapi_url=None`, это также отключит пользовательские интерфейсы документации, которые его использует.
|
||||
|
||||
## URL-адреса документации
|
||||
|
||||
Вы можете изменить конфигурацию двух пользовательских интерфейсов документации, среди которых
|
||||
|
||||
* **Swagger UI**: отображаемый по адресу `/docs`.
|
||||
* Вы можете задать его URL с помощью параметра `docs_url`.
|
||||
* Вы можете отключить это с помощью настройки `docs_url=None`.
|
||||
* **ReDoc**: отображаемый по адресу `/redoc`.
|
||||
* Вы можете задать его URL с помощью параметра `redoc_url`.
|
||||
* Вы можете отключить это с помощью настройки `redoc_url=None`.
|
||||
|
||||
К примеру, чтобы задать отображение Swagger UI по адресу `/documentation` и отключить ReDoc:
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!../../../docs_src/metadata/tutorial003.py!}
|
||||
```
|
||||
179
docs/ru/docs/tutorial/path-operation-configuration.md
Normal file
@@ -0,0 +1,179 @@
|
||||
# Конфигурация операций пути
|
||||
|
||||
Существует несколько параметров, которые вы можете передать вашему *декоратору операций пути* для его настройки.
|
||||
|
||||
!!! warning "Внимание"
|
||||
Помните, что эти параметры передаются непосредственно *декоратору операций пути*, а не вашей *функции-обработчику операций пути*.
|
||||
|
||||
## Коды состояния
|
||||
|
||||
Вы можете определить (HTTP) `status_code`, который будет использован в ответах вашей *операции пути*.
|
||||
|
||||
Вы можете передать только `int`-значение кода, например `404`.
|
||||
|
||||
Но если вы не помните, для чего нужен каждый числовой код, вы можете использовать сокращенные константы в параметре `status`:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="1 15"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="3 17"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial001_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="3 17"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial001.py!}
|
||||
```
|
||||
|
||||
Этот код состояния будет использован в ответе и будет добавлен в схему OpenAPI.
|
||||
|
||||
!!! note "Технические детали"
|
||||
Вы также можете использовать `from starlette import status`.
|
||||
|
||||
**FastAPI** предоставляет тот же `starlette.status` под псевдонимом `fastapi.status` для удобства разработчика. Но его источник - это непосредственно Starlette.
|
||||
|
||||
## Теги
|
||||
|
||||
Вы можете добавлять теги к вашим *операциям пути*, добавив параметр `tags` с `list` заполненным `str`-значениями (обычно в нём только одна строка):
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="15 20 25"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="17 22 27"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial002_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="17 22 27"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial002.py!}
|
||||
```
|
||||
|
||||
Они будут добавлены в схему OpenAPI и будут использованы в автоматической документации интерфейса:
|
||||
|
||||
<img src="/img/tutorial/path-operation-configuration/image01.png">
|
||||
|
||||
### Теги с перечислениями
|
||||
|
||||
Если у вас большое приложение, вы можете прийти к необходимости добавить **несколько тегов**, и возможно, вы захотите убедиться в том, что всегда используете **один и тот же тег** для связанных *операций пути*.
|
||||
|
||||
В этих случаях, имеет смысл хранить теги в классе `Enum`.
|
||||
|
||||
**FastAPI** поддерживает это так же, как и в случае с обычными строками:
|
||||
|
||||
```Python hl_lines="1 8-10 13 18"
|
||||
{!../../../docs_src/path_operation_configuration/tutorial002b.py!}
|
||||
```
|
||||
|
||||
## Краткое и развёрнутое содержание
|
||||
|
||||
Вы можете добавить параметры `summary` и `description`:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="18-19"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="20-21"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial003_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="20-21"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial003.py!}
|
||||
```
|
||||
|
||||
## Описание из строк документации
|
||||
|
||||
Так как описания обычно длинные и содержат много строк, вы можете объявить описание *операции пути* в функции <abbr title="многострочный текст, первое выражение внутри функции (не присвоенный какой-либо переменной), используемый для документации">строки документации</abbr> и **FastAPI** прочитает её отсюда.
|
||||
|
||||
Вы можете использовать <a href="https://en.wikipedia.org/wiki/Markdown" class="external-link" target="_blank">Markdown</a> в строке документации, и он будет интерпретирован и отображён корректно (с учетом отступа в строке документации).
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="17-25"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="19-27"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial004_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="19-27"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial004.py!}
|
||||
```
|
||||
|
||||
Он будет использован в интерактивной документации:
|
||||
|
||||
<img src="/img/tutorial/path-operation-configuration/image02.png">
|
||||
|
||||
## Описание ответа
|
||||
|
||||
Вы можете указать описание ответа с помощью параметра `response_description`:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="21"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial005_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="21"
|
||||
{!> ../../../docs_src/path_operation_configuration/tutorial005.py!}
|
||||
```
|
||||
|
||||
!!! info "Дополнительная информация"
|
||||
Помните, что `response_description` относится конкретно к ответу, а `description` относится к *операции пути* в целом.
|
||||
|
||||
!!! check "Технические детали"
|
||||
OpenAPI указывает, что каждой *операции пути* необходимо описание ответа.
|
||||
|
||||
Если вдруг вы не укажете его, то **FastAPI** автоматически сгенерирует это описание с текстом "Successful response".
|
||||
|
||||
<img src="/img/tutorial/path-operation-configuration/image03.png">
|
||||
|
||||
## Обозначение *операции пути* как устаревшей
|
||||
|
||||
Если вам необходимо пометить *операцию пути* как <abbr title="устаревшее, не рекомендовано к использованию">устаревшую</abbr>, при этом не удаляя её, передайте параметр `deprecated`:
|
||||
|
||||
```Python hl_lines="16"
|
||||
{!../../../docs_src/path_operation_configuration/tutorial006.py!}
|
||||
```
|
||||
|
||||
Он будет четко помечен как устаревший в интерактивной документации:
|
||||
|
||||
<img src="/img/tutorial/path-operation-configuration/image04.png">
|
||||
|
||||
Проверьте, как будут выглядеть устаревшие и не устаревшие *операции пути*:
|
||||
|
||||
<img src="/img/tutorial/path-operation-configuration/image05.png">
|
||||
|
||||
## Резюме
|
||||
|
||||
Вы можете легко конфигурировать и добавлять метаданные в ваши *операции пути*, передавая параметры *декораторам операций пути*.
|
||||
292
docs/ru/docs/tutorial/path-params-numeric-validations.md
Normal file
@@ -0,0 +1,292 @@
|
||||
# Path-параметры и валидация числовых данных
|
||||
|
||||
Так же, как с помощью `Query` вы можете добавлять валидацию и метаданные для query-параметров, так и с помощью `Path` вы можете добавлять такую же валидацию и метаданные для path-параметров.
|
||||
|
||||
## Импорт Path
|
||||
|
||||
Сначала импортируйте `Path` из `fastapi`, а также импортируйте `Annotated`:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="1 3"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="1 3"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="3-4"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! info "Информация"
|
||||
Поддержка `Annotated` была добавлена в FastAPI начиная с версии 0.95.0 (и с этой версии рекомендуется использовать этот подход).
|
||||
|
||||
Если вы используете более старую версию, вы столкнётесь с ошибками при попытке использовать `Annotated`.
|
||||
|
||||
Убедитесь, что вы [обновили версию FastAPI](../deployment/versions.md#upgrading-the-fastapi-versions){.internal-link target=_blank} как минимум до 0.95.1 перед тем, как использовать `Annotated`.
|
||||
|
||||
## Определите метаданные
|
||||
|
||||
Вы можете указать все те же параметры, что и для `Query`.
|
||||
|
||||
Например, чтобы указать значение метаданных `title` для path-параметра `item_id`, вы можете написать:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! note "Примечание"
|
||||
Path-параметр всегда является обязательным, поскольку он составляет часть пути.
|
||||
|
||||
Поэтому следует объявить его с помощью `...`, чтобы обозначить, что этот параметр обязательный.
|
||||
|
||||
Тем не менее, даже если вы объявите его как `None` или установите для него значение по умолчанию, это ни на что не повлияет и параметр останется обязательным.
|
||||
|
||||
## Задайте нужный вам порядок параметров
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Это не имеет большого значения, если вы используете `Annotated`.
|
||||
|
||||
Допустим, вы хотите объявить query-параметр `q` как обязательный параметр типа `str`.
|
||||
|
||||
И если вам больше ничего не нужно указывать для этого параметра, то нет необходимости использовать `Query`.
|
||||
|
||||
Но вам по-прежнему нужно использовать `Path` для path-параметра `item_id`. И если по какой-либо причине вы не хотите использовать `Annotated`, то могут возникнуть небольшие сложности.
|
||||
|
||||
Если вы поместите параметр со значением по умолчанию перед другим параметром, у которого нет значения по умолчанию, то Python укажет на ошибку.
|
||||
|
||||
Но вы можете изменить порядок параметров, чтобы параметр без значения по умолчанию (query-параметр `q`) шёл первым.
|
||||
|
||||
Это не имеет значения для **FastAPI**. Он распознает параметры по их названиям, типам и значениям по умолчанию (`Query`, `Path`, и т.д.), ему не важен их порядок.
|
||||
|
||||
Поэтому вы можете определить функцию так:
|
||||
|
||||
=== "Python 3.6 без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial002.py!}
|
||||
```
|
||||
|
||||
Но имейте в виду, что если вы используете `Annotated`, вы не столкнётесь с этой проблемой, так как вы не используете `Query()` или `Path()` в качестве значения по умолчанию для параметра функции.
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial002_an.py!}
|
||||
```
|
||||
|
||||
## Задайте нужный вам порядок параметров, полезные приёмы
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Это не имеет большого значения, если вы используете `Annotated`.
|
||||
|
||||
Здесь описан **небольшой приём**, который может оказаться удобным, хотя часто он вам не понадобится.
|
||||
|
||||
Если вы хотите:
|
||||
|
||||
* объявить query-параметр `q` без `Query` и без значения по умолчанию
|
||||
* объявить path-параметр `item_id` с помощью `Path`
|
||||
* указать их в другом порядке
|
||||
* не использовать `Annotated`
|
||||
|
||||
...то вы можете использовать специальную возможность синтаксиса Python.
|
||||
|
||||
Передайте `*` в качестве первого параметра функции.
|
||||
|
||||
Python не будет ничего делать с `*`, но он будет знать, что все следующие параметры являются именованными аргументами (парами ключ-значение), также известными как <abbr title="From: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>, даже если у них нет значений по умолчанию.
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!../../../docs_src/path_params_numeric_validations/tutorial003.py!}
|
||||
```
|
||||
|
||||
### Лучше с `Annotated`
|
||||
|
||||
Имейте в виду, что если вы используете `Annotated`, то, поскольку вы не используете значений по умолчанию для параметров функции, то у вас не возникнет подобной проблемы и вам не придётся использовать `*`.
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial003_an.py!}
|
||||
```
|
||||
|
||||
## Валидация числовых данных: больше или равно
|
||||
|
||||
С помощью `Query` и `Path` (и других классов, которые мы разберём позже) вы можете добавлять ограничения для числовых данных.
|
||||
|
||||
В этом примере при указании `ge=1`, параметр `item_id` должен быть больше или равен `1` ("`g`reater than or `e`qual").
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial004_an.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial004.py!}
|
||||
```
|
||||
|
||||
## Валидация числовых данных: больше и меньше или равно
|
||||
|
||||
То же самое применимо к:
|
||||
|
||||
* `gt`: больше (`g`reater `t`han)
|
||||
* `le`: меньше или равно (`l`ess than or `e`qual)
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial005_an.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial005.py!}
|
||||
```
|
||||
|
||||
## Валидация числовых данных: числа с плавающей точкой, больше и меньше
|
||||
|
||||
Валидация также применима к значениям типа `float`.
|
||||
|
||||
В этом случае становится важной возможность добавить ограничение <abbr title="greater than"><code>gt</code></abbr>, вместо <abbr title="greater than or equal"><code>ge</code></abbr>, поскольку в таком случае вы можете, например, создать ограничение, чтобы значение было больше `0`, даже если оно меньше `1`.
|
||||
|
||||
Таким образом, `0.5` будет корректным значением. А `0.0` или `0` — нет.
|
||||
|
||||
То же самое справедливо и для <abbr title="less than"><code>lt</code></abbr>.
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="13"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial006_an.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+ без Annotated"
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Рекомендуется использовать версию с `Annotated` если возможно.
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../../docs_src/path_params_numeric_validations/tutorial006.py!}
|
||||
```
|
||||
|
||||
## Резюме
|
||||
|
||||
С помощью `Query`, `Path` (и других классов, которые мы пока не затронули) вы можете добавлять метаданные и строковую валидацию тем же способом, как и в главе [Query-параметры и валидация строк](query-params-str-validations.md){.internal-link target=_blank}.
|
||||
|
||||
А также вы можете добавить валидацию числовых данных:
|
||||
|
||||
* `gt`: больше (`g`reater `t`han)
|
||||
* `ge`: больше или равно (`g`reater than or `e`qual)
|
||||
* `lt`: меньше (`l`ess `t`han)
|
||||
* `le`: меньше или равно (`l`ess than or `e`qual)
|
||||
|
||||
!!! info "Информация"
|
||||
`Query`, `Path` и другие классы, которые мы разберём позже, являются наследниками общего класса `Param`.
|
||||
|
||||
Все они используют те же параметры для дополнительной валидации и метаданных, которые вы видели ранее.
|
||||
|
||||
!!! note "Технические детали"
|
||||
`Query`, `Path` и другие "классы", которые вы импортируете из `fastapi`, на самом деле являются функциями, которые при вызове возвращают экземпляры одноимённых классов.
|
||||
|
||||
Объект `Query`, который вы импортируете, является функцией. И при вызове она возвращает экземпляр одноимённого класса `Query`.
|
||||
|
||||
Использование функций (вместо использования классов напрямую) нужно для того, чтобы ваш редактор не подсвечивал ошибки, связанные с их типами.
|
||||
|
||||
Таким образом вы можете использовать привычный вам редактор и инструменты разработки, не добавляя дополнительных конфигураций для игнорирования подобных ошибок.
|
||||
251
docs/ru/docs/tutorial/path-params.md
Normal file
@@ -0,0 +1,251 @@
|
||||
# Path-параметры
|
||||
|
||||
Вы можете определить "параметры" или "переменные" пути, используя синтаксис форматированных строк Python:
|
||||
|
||||
```Python hl_lines="6-7"
|
||||
{!../../../docs_src/path_params/tutorial001.py!}
|
||||
```
|
||||
|
||||
Значение параметра пути `item_id` будет передано в функцию в качестве аргумента `item_id`.
|
||||
|
||||
Если запустите этот пример и перейдёте по адресу: <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a>, то увидите ответ:
|
||||
|
||||
```JSON
|
||||
{"item_id":"foo"}
|
||||
```
|
||||
|
||||
## Параметры пути с типами
|
||||
|
||||
Вы можете объявить тип параметра пути в функции, используя стандартные аннотации типов Python.
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!../../../docs_src/path_params/tutorial002.py!}
|
||||
```
|
||||
|
||||
Здесь, `item_id` объявлен типом `int`.
|
||||
|
||||
!!! check "Заметка"
|
||||
Это обеспечит поддержку редактора внутри функции (проверка ошибок, автодополнение и т.п.).
|
||||
|
||||
## <abbr title="Или сериализация, парсинг">Преобразование</abbr> данных
|
||||
|
||||
Если запустите этот пример и перейдёте по адресу: <a href="http://127.0.0.1:8000/items/3" class="external-link" target="_blank">http://127.0.0.1:8000/items/3</a>, то увидите ответ:
|
||||
|
||||
```JSON
|
||||
{"item_id":3}
|
||||
```
|
||||
|
||||
!!! check "Заметка"
|
||||
Обратите внимание на значение `3`, которое получила (и вернула) функция. Это целочисленный Python `int`, а не строка `"3"`.
|
||||
|
||||
Используя определения типов, **FastAPI** выполняет автоматический <abbr title="преобразование строк из HTTP-запроса в типы данных Python">"парсинг"</abbr> запросов.
|
||||
|
||||
## <abbr title="Или валидация">Проверка</abbr> данных
|
||||
|
||||
Если откроете браузер по адресу <a href="http://127.0.0.1:8000/items/foo" class="external-link" target="_blank">http://127.0.0.1:8000/items/foo</a>, то увидите интересную HTTP-ошибку:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": [
|
||||
"path",
|
||||
"item_id"
|
||||
],
|
||||
"msg": "value is not a valid integer",
|
||||
"type": "type_error.integer"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
из-за того, что параметр пути `item_id` имеет значение `"foo"`, которое не является типом `int`.
|
||||
|
||||
Та же ошибка возникнет, если вместо `int` передать `float` , например: <a href="http://127.0.0.1:8000/items/4.2" class="external-link" target="_blank">http://127.0.0.1:8000/items/4.2</a>
|
||||
|
||||
!!! check "Заметка"
|
||||
**FastAPI** обеспечивает проверку типов, используя всё те же определения типов.
|
||||
|
||||
Обратите внимание, что в тексте ошибки явно указано место не прошедшее проверку.
|
||||
|
||||
Это очень полезно при разработке и отладке кода, который взаимодействует с API.
|
||||
|
||||
## Документация
|
||||
|
||||
И теперь, когда откроете браузер по адресу: <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>, то увидите вот такую автоматически сгенерированную документацию API:
|
||||
|
||||
<img src="/img/tutorial/path-params/image01.png">
|
||||
|
||||
!!! check "Заметка"
|
||||
Ещё раз, просто используя определения типов, **FastAPI** обеспечивает автоматическую интерактивную документацию (с интеграцией Swagger UI).
|
||||
|
||||
Обратите внимание, что параметр пути объявлен целочисленным.
|
||||
|
||||
## Преимущества стандартизации, альтернативная документация
|
||||
|
||||
Поскольку сгенерированная схема соответствует стандарту <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md" class="external-link" target="_blank">OpenAPI</a>, её можно использовать со множеством совместимых инструментов.
|
||||
|
||||
Именно поэтому, FastAPI сам предоставляет альтернативную документацию API (используя ReDoc), которую можно получить по адресу: <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
|
||||
|
||||
<img src="/img/tutorial/path-params/image02.png">
|
||||
|
||||
По той же причине, есть множество совместимых инструментов, включая инструменты генерации кода для многих языков.
|
||||
|
||||
## Pydantic
|
||||
|
||||
Вся проверка данных выполняется под капотом с помощью <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a>. Поэтому вы можете быть уверены в качестве обработки данных.
|
||||
|
||||
Вы можете использовать в аннотациях как простые типы данных, вроде `str`, `float`, `bool`, так и более сложные типы.
|
||||
|
||||
Некоторые из них рассматриваются в следующих главах данного руководства.
|
||||
|
||||
## Порядок имеет значение
|
||||
|
||||
При создании *операций пути* можно столкнуться с ситуацией, когда путь является фиксированным.
|
||||
|
||||
Например, `/users/me`. Предположим, что это путь для получения данных о текущем пользователе.
|
||||
|
||||
У вас также может быть путь `/users/{user_id}`, чтобы получить данные о конкретном пользователе по его ID.
|
||||
|
||||
Поскольку *операции пути* выполняются в порядке их объявления, необходимо, чтобы путь для `/users/me` был объявлен раньше, чем путь для `/users/{user_id}`:
|
||||
|
||||
|
||||
```Python hl_lines="6 11"
|
||||
{!../../../docs_src/path_params/tutorial003.py!}
|
||||
```
|
||||
|
||||
Иначе путь для `/users/{user_id}` также будет соответствовать `/users/me`, "подразумевая", что он получает параметр `user_id` со значением `"me"`.
|
||||
|
||||
Аналогично, вы не можете переопределить операцию с путем:
|
||||
|
||||
```Python hl_lines="6 11"
|
||||
{!../../../docs_src/path_params/tutorial003b.py!}
|
||||
```
|
||||
|
||||
Первый будет выполняться всегда, так как путь совпадает первым.
|
||||
|
||||
## Предопределенные значения
|
||||
|
||||
Что если нам нужно заранее определить допустимые *параметры пути*, которые *операция пути* может принимать? В таком случае можно использовать стандартное перечисление <abbr title="Enumeration">`Enum`</abbr> Python.
|
||||
|
||||
### Создание класса `Enum`
|
||||
|
||||
Импортируйте `Enum` и создайте подкласс, который наследуется от `str` и `Enum`.
|
||||
|
||||
Мы наследуемся от `str`, чтобы документация API могла понять, что значения должны быть типа `string` и отображалась правильно.
|
||||
|
||||
Затем создайте атрибуты класса с фиксированными допустимыми значениями:
|
||||
|
||||
```Python hl_lines="1 6-9"
|
||||
{!../../../docs_src/path_params/tutorial005.py!}
|
||||
```
|
||||
|
||||
!!! info "Дополнительная информация"
|
||||
<a href="https://docs.python.org/3/library/enum.html" class="external-link" target="_blank">Перечисления (enum) доступны в Python</a> начиная с версии 3.4.
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Если интересно, то "AlexNet", "ResNet" и "LeNet" - это названия <abbr title="Технически, это архитектуры моделей глубокого обучения">моделей</abbr> машинного обучения.
|
||||
|
||||
### Определение *параметра пути*
|
||||
|
||||
Определите *параметр пути*, используя в аннотации типа класс перечисления (`ModelName`), созданный ранее:
|
||||
|
||||
```Python hl_lines="16"
|
||||
{!../../../docs_src/path_params/tutorial005.py!}
|
||||
```
|
||||
|
||||
### Проверьте документацию
|
||||
|
||||
Поскольку доступные значения *параметра пути* определены заранее, интерактивная документация может наглядно их отображать:
|
||||
|
||||
<img src="/img/tutorial/path-params/image03.png">
|
||||
|
||||
### Работа с *перечислениями* в Python
|
||||
|
||||
Значение *параметра пути* будет *элементом перечисления*.
|
||||
|
||||
#### Сравнение *элементов перечисления*
|
||||
|
||||
Вы можете сравнить это значение с *элементом перечисления* класса `ModelName`:
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!../../../docs_src/path_params/tutorial005.py!}
|
||||
```
|
||||
|
||||
#### Получение *значения перечисления*
|
||||
|
||||
Можно получить фактическое значение (в данном случае - `str`) с помощью `model_name.value` или в общем случае `your_enum_member.value`:
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!../../../docs_src/path_params/tutorial005.py!}
|
||||
```
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Значение `"lenet"` также можно получить с помощью `ModelName.lenet.value`.
|
||||
|
||||
#### Возврат *элементов перечисления*
|
||||
|
||||
Из *операции пути* можно вернуть *элементы перечисления*, даже вложенные в тело JSON (например в `dict`).
|
||||
|
||||
Они будут преобразованы в соответствующие значения (в данном случае - строки) перед их возвратом клиенту:
|
||||
|
||||
```Python hl_lines="18 21 23"
|
||||
{!../../../docs_src/path_params/tutorial005.py!}
|
||||
```
|
||||
Вы отправите клиенту такой JSON-ответ:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"model_name": "alexnet",
|
||||
"message": "Deep Learning FTW!"
|
||||
}
|
||||
```
|
||||
|
||||
## Path-параметры, содержащие пути
|
||||
|
||||
Предположим, что есть *операция пути* с путем `/files/{file_path}`.
|
||||
|
||||
Но вам нужно, чтобы `file_path` сам содержал *путь*, например, `home/johndoe/myfile.txt`.
|
||||
|
||||
Тогда URL для этого файла будет такой: `/files/home/johndoe/myfile.txt`.
|
||||
|
||||
### Поддержка OpenAPI
|
||||
|
||||
OpenAPI не поддерживает способов объявления *параметра пути*, содержащего внутри *путь*, так как это может привести к сценариям, которые сложно определять и тестировать.
|
||||
|
||||
Тем не менее это можно сделать в **FastAPI**, используя один из внутренних инструментов Starlette.
|
||||
|
||||
Документация по-прежнему будет работать, хотя и не добавит никакой информации о том, что параметр должен содержать путь.
|
||||
|
||||
### Конвертер пути
|
||||
|
||||
Благодаря одной из опций Starlette, можете объявить *параметр пути*, содержащий *путь*, используя URL вроде:
|
||||
|
||||
```
|
||||
/files/{file_path:path}
|
||||
```
|
||||
|
||||
В этом случае `file_path` - это имя параметра, а часть `:path`, указывает, что параметр должен соответствовать любому *пути*.
|
||||
|
||||
Можете использовать так:
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!../../../docs_src/path_params/tutorial004.py!}
|
||||
```
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Возможно, вам понадобится, чтобы параметр содержал `/home/johndoe/myfile.txt` с ведущим слэшем (`/`).
|
||||
|
||||
В этом случае URL будет таким: `/files//home/johndoe/myfile.txt`, с двойным слэшем (`//`) между `files` и `home`.
|
||||
|
||||
## Резюме
|
||||
Используя **FastAPI** вместе со стандартными объявлениями типов Python (короткими и интуитивно понятными), вы получаете:
|
||||
|
||||
* Поддержку редактора (проверку ошибок, автозаполнение и т.п.)
|
||||
* "<abbr title="преобразование строк из HTTP-запроса в типы данных Python">Парсинг</abbr>" данных
|
||||
* Валидацию данных
|
||||
* Автоматическую документацию API с указанием типов параметров.
|
||||
|
||||
И объявлять типы достаточно один раз.
|
||||
|
||||
Это, вероятно, является главным заметным преимуществом **FastAPI** по сравнению с альтернативными фреймворками (кроме <abbr title="не считая оптимизаций">сырой</abbr> производительности).
|
||||
225
docs/ru/docs/tutorial/query-params.md
Normal file
@@ -0,0 +1,225 @@
|
||||
# Query-параметры
|
||||
|
||||
Когда вы объявляете параметры функции, которые не являются параметрами пути, они автоматически интерпретируются как "query"-параметры.
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../../docs_src/query_params/tutorial001.py!}
|
||||
```
|
||||
|
||||
Query-параметры представляют из себя набор пар ключ-значение, которые идут после знака `?` в URL-адресе, разделенные символами `&`.
|
||||
|
||||
Например, в этом URL-адресе:
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/items/?skip=0&limit=10
|
||||
```
|
||||
|
||||
...параметры запроса такие:
|
||||
|
||||
* `skip`: со значением `0`
|
||||
* `limit`: со значением `10`
|
||||
|
||||
Будучи частью URL-адреса, они "по умолчанию" являются строками.
|
||||
|
||||
Но когда вы объявляете их с использованием аннотаций (в примере выше, как `int`), они конвертируются в указанный тип данных и проходят проверку на соответствие ему.
|
||||
|
||||
Все те же правила, которые применяются к path-параметрам, также применяются и query-параметрам:
|
||||
|
||||
* Поддержка от редактора кода (очевидно)
|
||||
* <abbr title="преобразование строки, полученной из HTTP запроса в Python данные">"Парсинг"</abbr> данных
|
||||
* Проверка на соответствие данных (Валидация)
|
||||
* Автоматическая документация
|
||||
|
||||
## Значения по умолчанию
|
||||
|
||||
Поскольку query-параметры не являются фиксированной частью пути, они могут быть не обязательными и иметь значения по умолчанию.
|
||||
|
||||
В примере выше значения по умолчанию равны `skip=0` и `limit=10`.
|
||||
|
||||
Таким образом, результат перехода по URL-адресу:
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/items/
|
||||
```
|
||||
|
||||
будет таким же, как если перейти используя параметры по умолчанию:
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/items/?skip=0&limit=10
|
||||
```
|
||||
|
||||
Но если вы введёте, например:
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/items/?skip=20
|
||||
```
|
||||
|
||||
Значения параметров в вашей функции будут:
|
||||
|
||||
* `skip=20`: потому что вы установили это в URL-адресе
|
||||
* `limit=10`: т.к это было значение по умолчанию
|
||||
|
||||
## Необязательные параметры
|
||||
|
||||
Аналогично, вы можете объявлять необязательные query-параметры, установив их значение по умолчанию, равное `None`:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/query_params/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/query_params/tutorial002.py!}
|
||||
```
|
||||
|
||||
В этом случае, параметр `q` будет не обязательным и будет иметь значение `None` по умолчанию.
|
||||
|
||||
!!! Важно
|
||||
Также обратите внимание, что **FastAPI** достаточно умён чтобы заметить, что параметр `item_id` является path-параметром, а `q` нет, поэтому, это параметр запроса.
|
||||
|
||||
## Преобразование типа параметра запроса
|
||||
|
||||
Вы также можете объявлять параметры с типом `bool`, которые будут преобразованы соответственно:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../../docs_src/query_params/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../../docs_src/query_params/tutorial003.py!}
|
||||
```
|
||||
|
||||
В этом случае, если вы сделаете запрос:
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/items/foo?short=1
|
||||
```
|
||||
|
||||
или
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/items/foo?short=True
|
||||
```
|
||||
|
||||
или
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/items/foo?short=true
|
||||
```
|
||||
|
||||
или
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/items/foo?short=on
|
||||
```
|
||||
|
||||
или
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/items/foo?short=yes
|
||||
```
|
||||
|
||||
или в любом другом варианте написания (в верхнем регистре, с заглавной буквой, и т.п), внутри вашей функции параметр `short` будет иметь значение `True` типа данных `bool` . В противном случае - `False`.
|
||||
|
||||
|
||||
## Смешивание query-параметров и path-параметров
|
||||
|
||||
Вы можете объявлять несколько query-параметров и path-параметров одновременно,**FastAPI** сам разберётся, что чем является.
|
||||
|
||||
И вы не обязаны объявлять их в каком-либо определенном порядке.
|
||||
|
||||
Они будут обнаружены по именам:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="6 8"
|
||||
{!> ../../../docs_src/query_params/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="8 10"
|
||||
{!> ../../../docs_src/query_params/tutorial004.py!}
|
||||
```
|
||||
|
||||
## Обязательные query-параметры
|
||||
|
||||
Когда вы объявляете значение по умолчанию для параметра, который не является path-параметром (в этом разделе, мы пока что познакомились только с path-параметрами), то это значение не является обязательным.
|
||||
|
||||
Если вы не хотите задавать конкретное значение, но хотите сделать параметр необязательным, вы можете установить значение по умолчанию равным `None`.
|
||||
|
||||
Но если вы хотите сделать query-параметр обязательным, вы можете просто не указывать значение по умолчанию:
|
||||
|
||||
```Python hl_lines="6-7"
|
||||
{!../../../docs_src/query_params/tutorial005.py!}
|
||||
```
|
||||
|
||||
Здесь параметр запроса `needy` является обязательным параметром с типом данных `str`.
|
||||
|
||||
Если вы откроете в браузере URL-адрес, например:
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/items/foo-item
|
||||
```
|
||||
|
||||
...без добавления обязательного параметра `needy`, вы увидите подобного рода ошибку:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"detail": [
|
||||
{
|
||||
"loc": [
|
||||
"query",
|
||||
"needy"
|
||||
],
|
||||
"msg": "field required",
|
||||
"type": "value_error.missing"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Поскольку `needy` является обязательным параметром, вам необходимо указать его в URL-адресе:
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
|
||||
```
|
||||
|
||||
...это будет работать:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"item_id": "foo-item",
|
||||
"needy": "sooooneedy"
|
||||
}
|
||||
```
|
||||
|
||||
Конечно, вы можете определить некоторые параметры как обязательные, некоторые - со значением по умполчанию, а некоторые - полностью необязательные:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../../docs_src/query_params/tutorial006_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../../docs_src/query_params/tutorial006.py!}
|
||||
```
|
||||
|
||||
В этом примере, у нас есть 3 параметра запроса:
|
||||
|
||||
* `needy`, обязательный `str`.
|
||||
* `skip`, типа `int` и со значением по умолчанию `0`.
|
||||
* `limit`, необязательный `int`.
|
||||
|
||||
!!! подсказка
|
||||
Вы можете использовать класс `Enum` также, как ранее применяли его с [Path-параметрами](path-params.md#predefined-values){.internal-link target=_blank}.
|
||||
89
docs/ru/docs/tutorial/response-status-code.md
Normal file
@@ -0,0 +1,89 @@
|
||||
# HTTP коды статуса ответа
|
||||
|
||||
Вы можете задать HTTP код статуса ответа с помощью параметра `status_code` подобно тому, как вы определяете схему ответа в любой из *операций пути*:
|
||||
|
||||
* `@app.get()`
|
||||
* `@app.post()`
|
||||
* `@app.put()`
|
||||
* `@app.delete()`
|
||||
* и других.
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!../../../docs_src/response_status_code/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! note "Примечание"
|
||||
Обратите внимание, что `status_code` является атрибутом метода-декоратора (`get`, `post` и т.д.), а не *функции-обработчика пути* в отличие от всех остальных параметров и тела запроса.
|
||||
|
||||
Параметр `status_code` принимает число, обозначающее HTTP код статуса ответа.
|
||||
|
||||
!!! info "Информация"
|
||||
В качестве значения параметра `status_code` также может использоваться `IntEnum`, например, из библиотеки <a href="https://docs.python.org/3/library/http.html#http.HTTPStatus" class="external-link" target="_blank">`http.HTTPStatus`</a> в Python.
|
||||
|
||||
Это позволит:
|
||||
|
||||
* Возвращать указанный код статуса в ответе.
|
||||
* Документировать его как код статуса ответа в OpenAPI схеме (а значит, и в пользовательском интерфейсе):
|
||||
|
||||
<img src="/img/tutorial/response-status-code/image01.png">
|
||||
|
||||
!!! note "Примечание"
|
||||
Некоторые коды статуса ответа (см. следующий раздел) указывают на то, что ответ не имеет тела.
|
||||
|
||||
FastAPI знает об этом и создаст документацию OpenAPI, в которой будет указано, что тело ответа отсутствует.
|
||||
|
||||
## Об HTTP кодах статуса ответа
|
||||
|
||||
!!! note "Примечание"
|
||||
Если вы уже знаете, что представляют собой HTTP коды статуса ответа, можете перейти к следующему разделу.
|
||||
|
||||
В протоколе HTTP числовой код состояния из 3 цифр отправляется как часть ответа.
|
||||
|
||||
У кодов статуса есть названия, чтобы упростить их распознавание, но важны именно числовые значения.
|
||||
|
||||
Кратко о значениях кодов:
|
||||
|
||||
* `1XX` – статус-коды информационного типа. Они редко используются разработчиками напрямую. Ответы с этими кодами не могут иметь тела.
|
||||
* **`2XX`** – статус-коды, сообщающие об успешной обработке запроса. Они используются чаще всего.
|
||||
* `200` – это код статуса ответа по умолчанию, который означает, что все прошло "OK".
|
||||
* Другим примером может быть статус `201`, "Created". Он обычно используется после создания новой записи в базе данных.
|
||||
* Особый случай – `204`, "No Content". Этот статус ответа используется, когда нет содержимого для возврата клиенту, и поэтому ответ не должен иметь тела.
|
||||
* **`3XX`** – статус-коды, сообщающие о перенаправлениях. Ответы с этими кодами статуса могут иметь или не иметь тело, за исключением ответов со статусом `304`, "Not Modified", у которых не должно быть тела.
|
||||
* **`4XX`** – статус-коды, сообщающие о клиентской ошибке. Это ещё одна наиболее часто используемая категория.
|
||||
* Пример – код `404` для статуса "Not Found".
|
||||
* Для общих ошибок со стороны клиента можно просто использовать код `400`.
|
||||
* `5XX` – статус-коды, сообщающие о серверной ошибке. Они почти никогда не используются разработчиками напрямую. Когда что-то идет не так в какой-то части кода вашего приложения или на сервере, он автоматически вернёт один из 5XX кодов.
|
||||
|
||||
!!! tip "Подсказка"
|
||||
Чтобы узнать больше о HTTP кодах статуса и о том, для чего каждый из них предназначен, ознакомьтесь с <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" class="external-link" target="_blank">документацией <abbr title="Mozilla Developer Network">MDN</abbr> об HTTP кодах статуса ответа</a>.
|
||||
|
||||
## Краткие обозначения для запоминания названий кодов
|
||||
|
||||
Рассмотрим предыдущий пример еще раз:
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!../../../docs_src/response_status_code/tutorial001.py!}
|
||||
```
|
||||
|
||||
`201` – это код статуса "Создано".
|
||||
|
||||
Но вам не обязательно запоминать, что означает каждый из этих кодов.
|
||||
|
||||
Для удобства вы можете использовать переменные из `fastapi.status`.
|
||||
|
||||
```Python hl_lines="1 6"
|
||||
{!../../../docs_src/response_status_code/tutorial002.py!}
|
||||
```
|
||||
|
||||
Они содержат те же числовые значения, но позволяют использовать подсказки редактора для выбора кода статуса:
|
||||
|
||||
<img src="/img/tutorial/response-status-code/image02.png">
|
||||
|
||||
!!! note "Технические детали"
|
||||
Вы также можете использовать `from starlette import status` вместо `from fastapi import status`.
|
||||
|
||||
**FastAPI** позволяет использовать как `starlette.status`, так и `fastapi.status` исключительно для удобства разработчиков. Но поставляется fastapi.status непосредственно из Starlette.
|
||||
|
||||
## Изменение кода статуса по умолчанию
|
||||
|
||||
Позже, в [Руководстве для продвинутых пользователей](../advanced/response-change-status-code.md){.internal-link target=_blank}, вы узнаете, как возвращать HTTP коды статуса, отличные от используемого здесь кода статуса по умолчанию.
|
||||
189
docs/ru/docs/tutorial/schema-extra-example.md
Normal file
@@ -0,0 +1,189 @@
|
||||
# Объявление примера запроса данных
|
||||
|
||||
Вы можете объявлять примеры данных, которые ваше приложение может получать.
|
||||
|
||||
Вот несколько способов, как это можно сделать.
|
||||
|
||||
## Pydantic `schema_extra`
|
||||
|
||||
Вы можете объявить ключ `example` для модели Pydantic, используя класс `Config` и переменную `schema_extra`, как описано в <a href="https://pydantic-docs.helpmanual.io/usage/schema/#schema-customization" class="external-link" target="_blank">Pydantic документации: Настройка схемы</a>:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="13-21"
|
||||
{!> ../../../docs_src/schema_extra_example/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="15-23"
|
||||
{!> ../../../docs_src/schema_extra_example/tutorial001.py!}
|
||||
```
|
||||
|
||||
Эта дополнительная информация будет включена в **JSON Schema** выходных данных для этой модели, и она будет использоваться в документации к API.
|
||||
|
||||
!!! tip Подсказка
|
||||
Вы можете использовать тот же метод для расширения JSON-схемы и добавления своей собственной дополнительной информации.
|
||||
|
||||
Например, вы можете использовать это для добавления дополнительной информации для пользовательского интерфейса в вашем веб-приложении и т.д.
|
||||
|
||||
## Дополнительные аргументы поля `Field`
|
||||
|
||||
При использовании `Field()` с моделями Pydantic, вы также можете объявлять дополнительную информацию для **JSON Schema**, передавая любые другие произвольные аргументы в функцию.
|
||||
|
||||
Вы можете использовать это, чтобы добавить аргумент `example` для каждого поля:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="2 8-11"
|
||||
{!> ../../../docs_src/schema_extra_example/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="4 10-13"
|
||||
{!> ../../../docs_src/schema_extra_example/tutorial002.py!}
|
||||
```
|
||||
|
||||
!!! warning Внимание
|
||||
Имейте в виду, что эти дополнительные переданные аргументы не добавляют никакой валидации, только дополнительную информацию для документации.
|
||||
|
||||
## Использование `example` и `examples` в OpenAPI
|
||||
|
||||
При использовании любой из этих функций:
|
||||
|
||||
* `Path()`
|
||||
* `Query()`
|
||||
* `Header()`
|
||||
* `Cookie()`
|
||||
* `Body()`
|
||||
* `Form()`
|
||||
* `File()`
|
||||
|
||||
вы также можете добавить аргумент, содержащий `example` или группу `examples` с дополнительной информацией, которая будет добавлена в **OpenAPI**.
|
||||
|
||||
### Параметр `Body` с аргументом `example`
|
||||
|
||||
Здесь мы передаём аргумент `example`, как пример данных ожидаемых в параметре `Body()`:
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="22-27"
|
||||
{!> ../../../docs_src/schema_extra_example/tutorial003_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="22-27"
|
||||
{!> ../../../docs_src/schema_extra_example/tutorial003_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="23-28"
|
||||
{!> ../../../docs_src/schema_extra_example/tutorial003_an.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10+ non-Annotated"
|
||||
|
||||
!!! tip Заметка
|
||||
Рекомендуется использовать версию с `Annotated`, если это возможно.
|
||||
|
||||
```Python hl_lines="18-23"
|
||||
{!> ../../../docs_src/schema_extra_example/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+ non-Annotated"
|
||||
|
||||
!!! tip Заметка
|
||||
Рекомендуется использовать версию с `Annotated`, если это возможно.
|
||||
|
||||
```Python hl_lines="20-25"
|
||||
{!> ../../../docs_src/schema_extra_example/tutorial003.py!}
|
||||
```
|
||||
|
||||
### Аргумент "example" в UI документации
|
||||
|
||||
С любым из вышеуказанных методов это будет выглядеть так в `/docs`:
|
||||
|
||||
<img src="/img/tutorial/body-fields/image01.png">
|
||||
|
||||
### `Body` с аргументом `examples`
|
||||
|
||||
В качестве альтернативы одному аргументу `example`, вы можете передавать `examples` используя тип данных `dict` с **несколькими примерами**, каждый из которых содержит дополнительную информацию, которая также будет добавлена в **OpenAPI**.
|
||||
|
||||
Ключи `dict` указывают на каждый пример, а значения для каждого из них - на еще один тип `dict` с дополнительной информацией.
|
||||
|
||||
Каждый конкретный пример типа `dict` в аргументе `examples` может содержать:
|
||||
|
||||
* `summary`: Краткое описание для примера.
|
||||
* `description`: Полное описание, которое может содержать текст в формате Markdown.
|
||||
* `value`: Это конкретный пример, который отображается, например, в виде типа `dict`.
|
||||
* `externalValue`: альтернатива параметру `value`, URL-адрес, указывающий на пример. Хотя это может не поддерживаться таким же количеством инструментов разработки и тестирования API, как параметр `value`.
|
||||
|
||||
=== "Python 3.10+"
|
||||
|
||||
```Python hl_lines="23-49"
|
||||
{!> ../../../docs_src/schema_extra_example/tutorial004_an_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.9+"
|
||||
|
||||
```Python hl_lines="23-49"
|
||||
{!> ../../../docs_src/schema_extra_example/tutorial004_an_py39.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+"
|
||||
|
||||
```Python hl_lines="24-50"
|
||||
{!> ../../../docs_src/schema_extra_example/tutorial004_an.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.10+ non-Annotated"
|
||||
|
||||
!!! tip Заметка
|
||||
Рекомендуется использовать версию с `Annotated`, если это возможно.
|
||||
|
||||
```Python hl_lines="19-45"
|
||||
{!> ../../../docs_src/schema_extra_example/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
=== "Python 3.6+ non-Annotated"
|
||||
|
||||
!!! tip Заметка
|
||||
Рекомендуется использовать версию с `Annotated`, если это возможно.
|
||||
|
||||
```Python hl_lines="21-47"
|
||||
{!> ../../../docs_src/schema_extra_example/tutorial004.py!}
|
||||
```
|
||||
|
||||
### Аргумент "examples" в UI документации
|
||||
|
||||
С аргументом `examples`, добавленным в `Body()`, страница документации `/docs` будет выглядеть так:
|
||||
|
||||
<img src="/img/tutorial/body-fields/image02.png">
|
||||
|
||||
## Технические Детали
|
||||
|
||||
!!! warning Внимание
|
||||
Эти технические детали относятся к стандартам **JSON Schema** и **OpenAPI**.
|
||||
|
||||
Если предложенные выше идеи уже работают для вас, возможно этого будет достаточно и эти детали вам не потребуются, можете спокойно их пропустить.
|
||||
|
||||
Когда вы добавляете пример внутрь модели Pydantic, используя `schema_extra` или `Field(example="something")`, этот пример добавляется в **JSON Schema** для данной модели Pydantic.
|
||||
|
||||
И эта **JSON Schema** модели Pydantic включается в **OpenAPI** вашего API, а затем используется в UI документации.
|
||||
|
||||
Поля `example` как такового не существует в стандартах **JSON Schema**. В последних версиях JSON-схемы определено поле <a href="https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9.5" class="external-link" target="_blank">`examples`</a>, но OpenAPI 3.0.3 основан на более старой версии JSON-схемы, которая не имела поля `examples`.
|
||||
|
||||
Таким образом, OpenAPI 3.0.3 определяет своё собственное поле <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#fixed-fields-20" class="external-link" target="_blank">`example`</a> для модифицированной версии **JSON Schema**, которую он использует чтобы достичь той же цели (однако это именно поле `example`, а не `examples`), и именно это используется API в UI документации (с интеграцией Swagger UI).
|
||||
|
||||
Итак, хотя поле `example` не является частью JSON-схемы, оно является частью настраиваемой версии JSON-схемы в OpenAPI, и именно это поле будет использоваться в UI документации.
|
||||
|
||||
Однако, когда вы используете поле `example` или `examples` с любой другой функцией (`Query()`, `Body()`, и т.д.), эти примеры не добавляются в JSON-схему, которая описывает эти данные (даже в собственную версию JSON-схемы OpenAPI), они добавляются непосредственно в объявление *операции пути* в OpenAPI (вне частей OpenAPI, которые используют JSON-схему).
|
||||
|
||||
Для функций `Path()`, `Query()`, `Header()`, и `Cookie()`, аргументы `example` или `examples` добавляются в <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#parameter-object" class="external-link" target="_blank">определение OpenAPI, к объекту `Parameter Object` (в спецификации)</a>.
|
||||
|
||||
И для функций `Body()`, `File()` и `Form()` аргументы `example` или `examples` аналогично добавляются в <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#mediaTypeObject" class="external-link" target="_blank"> определение OpenAPI, к объекту `Request Body Object`, в поле `content` в объекте `Media Type Object` (в спецификации)</a>.
|
||||
|
||||
С другой стороны, существует более новая версия OpenAPI: **3.1.0**, недавно выпущенная. Она основана на последней версии JSON-схемы и большинство модификаций из OpenAPI JSON-схемы удалены в обмен на новые возможности из последней версии JSON-схемы, так что все эти мелкие отличия устранены. Тем не менее, Swagger UI в настоящее время не поддерживает OpenAPI 3.1.0, поэтому пока лучше продолжать использовать вышеупомянутые методы.
|
||||